鱼C论坛

 找回密码
 立即注册
查看: 3417|回复: 12

UVa一道关于长方体的题。

[复制链接]
发表于 2021-1-17 19:32:56 | 显示全部楼层 |阅读模式
6鱼币
//题目大意:给定6个矩形的长和宽w,h(1<=w,h<=10000),判断它们能否构成长方体的6个面。
// UVa里的1587,uDebug全试了,都能过,结果还是Wrong Answer,想知道哪有问题,求大佬康康。

22.png
  1. #include<stdio.h>
  2. #include<string.h>

  3. const int N = 10005;
  4. int a[N][N];
  5. int s[N];

  6. int com(int a, int b, int c, int d)// 矩形ab与cd比较是否相同
  7. {
  8.         if(a == c && b == d) return 1;
  9.         else if(a == d && b == c ) return 1;
  10.         else return 0;
  11. }

  12. int main(){
  13.         while(scanf("%d%d", &a[0][0], &a[0][1]) != EOF ){
  14.         
  15.             for(int i = 1; i < 6; i++)
  16.                 scanf("%d%d", &a[i][0], &a[i][1]);
  17.             int max = a[0][0], min = a[0][0];
  18.         
  19.             for(int j = 0; j < 6; j++){
  20.                 for(int k = 0; k < 2; k ++){
  21.                     if(max < a[j][k]) max = a[j][k];
  22.                     if(min > a[j][k]) min = a[j][k];
  23.                     s[a[j][k]]++;
  24.                 }
  25.             }
  26.             int p = 0, sum = 0, x = 0, y = 0, z = 0, t = 0;
  27.             for(int i = min; i <= max; i++){
  28.                 if( s[i] && s[i] % 4 != 0) {    p = 1;break; }// 边数不是4的倍数
  29.                 if(s[i] && !t) {    x = i; t++; }// 长
  30.                 else if(s[i] && t == 1) {   y = i; t++; }// 宽
  31.                 else if(s[i] && t == 2){    z = i; t++; }// 高
  32.             }
  33.             if(p) { printf("IMPOSSIBLE\n");continue; }
  34.             if(!z){
  35.                 if(s[x] > s[y]) z = x;
  36.                 else z = y;
  37.             }// 长宽高只有两个数时
  38.             int xy = 0, xz = 0, yz = 0;
  39.             for(int i = 0; i < 6; i++){
  40.                 if(com(a[i][0], a[i][1], x, y)) xy ++;// 长宽
  41.                 else if(com(a[i][0], a[i][1], x, z)) xz ++; // 长高
  42.                 else if(com(a[i][0], a[i][1], z, y)) yz ++;// 宽高
  43.             }
  44.             if(xy % 2 != 0 || xz % 2 != 0 || yz % 2 != 0 || xy + xz + yz != 6) printf("IMPOSSIBLE\n");// 均应是2的倍数,且之和为6
  45.             else printf("POSSIBLE\n");
  46.             memset(a, 0, sizeof(a));
  47.             memset(s, 0, sizeof(s));
  48.         }
  49.         return 0;
  50. }
复制代码

小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2021-1-17 20:24:59 | 显示全部楼层
本帖最后由 jackz007 于 2021-1-17 20:30 编辑
  1. #include <stdio.h>

  2. // 给出 6 组长宽数据,判断是否可能构成长方体的 6 个面?

  3. int check(int d[6][2])
  4. {
  5.         int e[12] , f , i , j , k , m , * p , r                         ;
  6.         for(p = d[0] , f = 1 , r = i = 0 ; i < 12 ; i ++) {
  7.                 if(p[i] > 0) {
  8.                         e[i] = p[i]                                     ;
  9.                 } else {
  10.                         f = 0                                           ;
  11.                         break                                           ;
  12.                 }
  13.         }
  14.         if(f) {
  15.                 for(m = 12 , i = 0 ; i < m - 1 ; i ++) {
  16.                         for(j = i + 1 ; j < m ; j ++) {
  17.                                 while(e[i] == e[j] && j < m) {
  18.                                         for(k = j + 1 ; k < m ; k ++) {
  19.                                                 e[k - 1] = e[k]         ;
  20.                                         }
  21.                                         m --                            ;
  22.                                 }
  23.                         }
  24.                 }
  25.                 if(m < 4) r = 1                                         ;
  26.         }
  27.         return r                                                        ;
  28. }

  29. int main(void)
  30. {
  31.         int d[6][2] = {0} , i                                           ;
  32.         for(i = 0 ; i < 6; i ++) scanf("%d%d" , & d[i][0] , & d[i][1])  ;
  33.         if(check(d)) printf("Possible .\n")                             ;
  34.         else printf("Impossible .\n")                                   ;
  35. }
复制代码

        具体思路是,6 组 12 个数必须全都大于 0,在此基础上,删除重复的数据,如果最后剩下的数少于 4 个,那就必然是长方体的 6 个面无疑,否则,就一定不是。
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2021-1-17 20:45:32 | 显示全部楼层
jackz007 发表于 2021-1-17 20:24
具体思路是,6 组 12 个数必须全都大于 0,在此基础上,删除重复的数据,如果最后剩下的数少于 4 ...

这个想法很好,但是有情况需要在斟酌一下最后三个面一定能构成吗?
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2021-1-17 20:48:57 | 显示全部楼层
不惜恋儿 发表于 2021-1-17 20:45
这个想法很好,但是有情况需要在斟酌一下最后三个面一定能构成吗?

回贴还不太熟悉,暂时发不了图片给你看。你刚刚的代码需要完善。。我这有样例:
  1. 1 2
  2. 2 1
  3. 3 1
  4. 2 2
  5. 1 2
  6. 3 3
  7. 3 2
  8. 1 1
  9. 1 1
  10. 3 2
  11. 2 3
  12. 3 1
  13. 1 2
  14. 3 1
  15. 3 1
  16. 3 3
  17. 3 2
  18. 3 2
  19. 3 1
  20. 2 1
  21. 1 3
  22. 2 2
  23. 3 2
  24. 2 3
  25. 2 1
  26. 1 2
  27. 3 1
  28. 3 1
  29. 2 3
  30. 3 3
  31. 3 3
  32. 1 1
  33. 2 3
  34. 3 3
  35. 2 2
  36. 2 3
  37. 2 2
  38. 3 1
  39. 1 2
  40. 2 2
  41. 1 2
  42. 3 3
  43. 1 1
  44. 1 3
  45. 2 3
  46. 2 1
  47. 1 1
  48. 2 3
  49. 1 2
  50. 1 2
  51. 1 2
  52. 1 3
  53. 3 1
  54. 2 2
  55. 1 3
  56. 2 2
  57. 1 1
  58. 2 2
  59. 2 2
  60. 1 2
  61. 3 3
  62. 2 1
  63. 3 3
  64. 3 3
  65. 1 1
  66. 3 3
  67. 3 3
  68. 3 2
  69. 3 2
  70. 2 2
  71. 3 3
  72. 2 2
  73. 3 1
  74. 2 3
  75. 3 1
  76. 1 3
  77. 3 2
  78. 2 3
  79. 3 3
  80. 2 2
  81. 3 1
  82. 1 1
  83. 3 2
  84. 2 1
  85. 3 2
  86. 3 1
  87. 2 3
  88. 1 1
  89. 1 2
  90. 3 3
  91. 3 3
  92. 2 2
  93. 1 3
  94. 2 1
  95. 3 1
  96. 2 1
  97. 3 2
  98. 2 3
  99. 3 2
  100. 1 3
  101. 1 3
  102. 2 1
  103. 1 3
  104. 1 1
  105. 3 2
  106. 3 2
  107. 3 2
  108. 1 1
  109. 2 3
  110. 1 3
  111. 1 2
  112. 1 3
  113. 2 3
  114. 2 2
  115. 2 2
  116. 2 3
  117. 3 3
  118. 2 1
  119. 1 1
  120. 3 3
复制代码

这些输出都是:
  1. IMPOSSIBLE
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2021-1-17 21:07:21 | 显示全部楼层
不惜恋儿 发表于 2021-1-17 20:48
回贴还不太熟悉,暂时发不了图片给你看。你刚刚的代码需要完善。。我这有样例:

这些输出都是:

          确实存在问题,再增加一个限制条件,筛出来的每个数在数组中都必须成对出现。
  1. #include <stdio.h>

  2. // 给出 6 组长宽数据,判断是否可能构成长方体的 6 个面?

  3. int check(int d[6][2])
  4. {
  5.         int c[3] = {0} , e[12] , f , i , j , k , m , * p , r            ;
  6.         for(p = d[0] , f = 1 , r = i = 0 ; i < 12 ; i ++) {
  7.                 if(p[i] > 0) {
  8.                         e[i] = p[i]                                     ;
  9.                 } else {
  10.                         f = 0                                           ;
  11.                         break                                           ;
  12.                 }
  13.         }
  14.         if(f) {
  15.                 for(m = 12 , i = 0 ; i < m - 1 ; i ++) {
  16.                         for(j = i + 1 ; j < m ; j ++) {
  17.                                 while(e[i] == e[j] && j < m) {
  18.                                         for(k = j + 1 ; k < m ; k ++) {
  19.                                                 e[k - 1] = e[k]         ;
  20.                                         }
  21.                                         m --                            ;
  22.                                 }
  23.                         }
  24.                 }
  25.                 if(m < 4){
  26.                         for(i = 0 ; i < 12 ; i ++) {
  27.                                 for(k = 0 ; k < m ; k ++) {
  28.                                         if(p[i] == e[k]) c[k] ++        ;
  29.                                 }
  30.                         }
  31.                         for(k = 0 ; k < m ; k ++) if(c[k] % 2) break    ;
  32.                         if(k == m) r = 1                                ;
  33.                 }
  34.         }
  35.         return r                                                        ;
  36. }

  37. int main(void)
  38. {
  39.         int d[6][2] = {0} , i                                           ;
  40.         for(i = 0 ; i < 6; i ++) scanf("%d%d" , & d[i][0] , & d[i][1])  ;
  41.         if(check(d)) printf("Possible .\n")                             ;
  42.         else printf("Impossible .\n")                                   ;
  43. }
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2021-1-17 21:50:47 | 显示全部楼层
jackz007 发表于 2021-1-17 21:07
确实存在问题,再增加一个限制条件,筛出来的每个数在数组中都必须成对出现。

我刚刚给出的测试点你那都是IMPOSSIBLE吗? 我这有点不一样。
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2021-1-17 21:54:45 | 显示全部楼层
不惜恋儿 发表于 2021-1-17 21:50
我刚刚给出的测试点你那都是IMPOSSIBLE吗? 我这有点不一样。

        举出一组有疑问的数据看看呢
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2021-1-17 21:59:16 | 显示全部楼层
jackz007 发表于 2021-1-17 21:07
确实存在问题,再增加一个限制条件,筛出来的每个数在数组中都必须成对出现。

每个数字都是2的倍数是可以的,但是如果像(1,1)(2,2)(3 ,3)||(1,1)(2,2)(1,1)也可以通过吗?
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2021-1-17 22:12:30 | 显示全部楼层
jackz007 发表于 2021-1-17 21:54
举出一组有疑问的数据看看呢
  1. 1 1
  2. 1 1
  3. 2 2
  4. 2 2
  5. 3 3
  6. 3 3
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2021-1-17 22:51:14 | 显示全部楼层
本帖最后由 jackz007 于 2021-1-18 00:39 编辑


        你举的这些反例非常说明问题,我又把代码改了。
        现在的判定逻辑是:
        1、所有的数据必须大于 0;
        2、6 个面可以归结到 3 个以内不同的面,而且,每个面成对出现;
        3、经过简化,所有面的数据可以归结为 3 个以内不同的数值(长、宽、高);
        
  1. #include <stdio.h>

  2. // 给出 6 组长宽数据,判断是否可能构成长方体的 6 个面?

  3. int check(int d[6][2])
  4. {
  5.         int c[3] = {0} , e[6][2] = {0} , f , i , j , k , m , * p , r            ;
  6.         for(f = 1 , i = 0 ; i < 6; i ++) {
  7.                 if(d[i][0] > 0 && d[i][1] > 0) {
  8.                         e[i][0] = d[i][0]                                       ;
  9.                         e[i][1] = d[i][1]                                       ;
  10.                 } else {
  11.                         f = 0                                                   ;
  12.                         break                                                   ;
  13.                 }
  14.         }
  15.         if(f) {
  16.                 for(m = 6 , r = i = 0 ; i < m - 1 ; i ++) {
  17.                         for(j = i + 1 ; j < m ; j ++) {
  18.                                 while(j < m && ((e[i][0] == e[j][0] && e[i][1] == e[j][1]) || (e[i][0] == e[j][1] && e[i][1] == e[j][0]))) {
  19.                                         for(k = j + 1 ; k < m ; k ++) {
  20.                                                 e[k - 1][0] = e[k][0]           ;
  21.                                                 e[k - 1][1] = e[k][1]           ;        
  22.                                         }
  23.                                         m --                                    ;
  24.                                 }
  25.                         }
  26.                 }        
  27.                 if(m < 4) {
  28.                         for(i = 0 ; i < 6 ; i ++) {
  29.                                 for(k = 0 ; k < m ; k ++) {
  30.                                         if((d[i][0] == e[k][0] && d[i][1] == e[k][1]) || (d[i][0] == e[k][1] && d[i][1] == e[k][0])) c[k] ++ ;
  31.                                 }        
  32.                         }
  33.                         for(i = 0 ; i < m ; i ++) if(c[i] % 2) break            ;
  34.                         if(i == m) {
  35.                                 for(p = e[0] , m *= 2 , i = 0 ; i < m - 1 ; i ++) {
  36.                                         for(j = i + 1 ; j < m ; j ++) {
  37.                                                 while(j < m && p[i] == p[j]) {
  38.                                                         for(k = j + 1 ; k < m ; k ++) {
  39.                                                                 p[k - 1] = p[k] ;
  40.                                                         }
  41.                                                         m --                    ;
  42.                                                 }
  43.                                         }
  44.                                 }
  45.                                 if(m < 4) r = 1                                 ;
  46.                         }
  47.                 }
  48.         }
  49.         return r                                                                ;
  50. }

  51. int main(void)
  52. {
  53.         int d[6][2] = {0} , i                                           ;
  54.         for(i = 0 ; i < 6 ; i ++) scanf("%d%d" , & d[i][0] , & d[i][1]) ;
  55.         if(check(d)) printf("Possible .\n")                             ;
  56.         else printf("Impossible .\n")                                   ;
  57. }
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2021-1-18 13:09:40 | 显示全部楼层
jackz007 发表于 2021-1-17 22:51
你举的这些反例非常说明问题,我又把代码改了。
        现在的判定逻辑是:
        1、所 ...

1 1
2 2
3 3
1 1
2 2
3 3
Possible .
你好,你的代码你有运行吗?我给你举的例子运行后还是可以构成。。。
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2021-1-18 14:01:13 | 显示全部楼层

        又改了,请你再测
  1. #include <stdio.h>

  2. // 给出 6 组长宽数据,判断是否可能构成长方体的 6 个面?

  3. int check(int d[6][2])
  4. {
  5.         int c[3] = {0} , e[6][2] = {0} , f , i , j , k , m , * p , r            ;
  6.         for(f = 1 , i = 0 ; i < 6; i ++) {
  7.                 if(d[i][0] > 0 && d[i][1] > 0) {
  8.                         e[i][0] = d[i][0]                                       ;
  9.                         e[i][1] = d[i][1]                                       ;
  10.                 } else {
  11.                         f = 0                                                   ;
  12.                         break                                                   ;
  13.                 }
  14.         }
  15.         if(f) {
  16.                 for(m = 6 , r = i = 0 ; i < m - 1 ; i ++) {
  17.                         for(j = i + 1 ; j < m ; j ++) {
  18.                                 while(j < m && ((e[i][0] == e[j][0] && e[i][1] == e[j][1]) || (e[i][0] == e[j][1] && e[i][1] == e[j][0]))) {
  19.                                         for(k = j + 1 ; k < m ; k ++) {
  20.                                                 e[k - 1][0] = e[k][0]           ;
  21.                                                 e[k - 1][1] = e[k][1]           ;        
  22.                                         }
  23.                                         m --                                    ;
  24.                                 }
  25.                         }
  26.                 }        
  27.                 if(m < 4) {
  28.                         for(k = i = 0 ; i < m - 1 ; i ++) {
  29.                                 for(j = i + 1 ; j < m ; j ++) {
  30.                                         if(e[i][0] == e[j][0] || e[i][1] == e[j][1] || e[i][1] == e[j][0] || e[i][0] == e[j][1]) k ++ ;
  31.                                 }
  32.                         }
  33.                         if(m == 1 || k == (m - 2) * 2 + 1) r = 1                ;
  34.                 }
  35.         }
  36.         return r                                                                                                                      ;
  37. }

  38. int main(void)
  39. {
  40.         int d[6][2] = {0} , i                                           ;
  41.         for(i = 0 ; i < 6 ; i ++) scanf("%d%d" , & d[i][0] , & d[i][1]) ;
  42.         if(check(d)) printf("Possible .\n")                             ;
  43.         else printf("Impossible .\n")                                   ;
  44. }
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2021-1-18 16:43:46 | 显示全部楼层
jackz007 发表于 2021-1-18 14:01
又改了,请你再测
  1. https://vjudge.net/problem/UVA-1587
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-5-2 07:43

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表