4-30ACM训练题解(ICPC Asia Taipei-Hsinchu Contest)

A Rush Hour Puzzle Gym - 102460A  by wxh

直接BFS即可,入过队的状态就不需要在入队了

  1 #include <bits/stdc++.h>
  2 using namespace std;
  3 int base = 131;
  4 struct Map{
  5   int a[6][6], Num;
  6   unsigned Hash;
  7   void Get_Hash() {
  8     Hash = 0;
  9     for (int i = 0; i < 6; i++) {
 10       for (int j = 0; j < 6; j++) {
 11         Hash = Hash * base + a[i][j];
 12       }
 13     }
 14   }
 15 }a, k;
 16 int v;
 17 queue<Map> Q;
 18 set<unsigned> st;
 19 bool flag[11];
 20 bool TryMove1(int a[][6], int i, int j, int op) {
 21   if (op == 1) {
 22     if (j + 2 == 6) return 0;
 23     if (a[i][j + 2] == 0) return 1;
 24     if (a[i][j + 2] != a[i][j]) return 0;
 25     if (j + 3 == 6) return 0;
 26     if (a[i][j + 3] == 0) return 1;
 27     if (a[i][j + 3] != a[i][j]) return 0;
 28   } else {
 29     if (j - 1 == -1) return 0;
 30     if (a[i][j - 1] == 0) return 1;
 31     if (a[i][j - 1] != 0) return 0;
 32   }
 33 }
 34 bool TryMove2(int a[][6], int i, int j, int op) {
 35   if (op == 1) {
 36     if (i + 2 == 6) return 0;
 37     if (a[i + 2][j] == 0) return 1;
 38     if (a[i + 2][j] != a[i][j]) return 0;
 39     if (i + 3 == 6) return 0;
 40     if (a[i + 3][j] == 0) return 1;
 41     if (a[i + 3][j] != a[i][j]) return 0;
 42   } else {
 43     if (i - 1 == -1) return 0;
 44     if (a[i - 1][j] == 0) return 1;
 45     if (a[i - 1][j] != 0) return 0;
 46   }
 47 }
 48 int main() {
 49   for (int i = 0; i < 6; i++) {
 50     for (int j = 0; j < 6; j++) {
 51       scanf ("%d", &a.a[i][j]);
 52     }
 53   }
 54   a.Get_Hash();
 55   a.Num = 0;
 56   Q.push(a);
 57   st.insert(a.Hash);
 58   while (!Q.empty()) {
 59     k = Q.front();
 60     memset (flag, 0, sizeof(flag));
 61     Q.pop();
 62     if (k.a[2][5] == 1 && k.a[2][4] == 1) {
 63       printf ("%d\n", k.Num + 2);
 64       return 0;
 65     }
 66     if (k.Num == 8) continue;
 67     for (int i = 0; i < 6; i++) {
 68       for (int j = 0; j < 6; j++) {
 69         if (k.a[i][j] != 0 && !flag[k.a[i][j]]) {
 70           flag[k.a[i][j]] = 1;
 71           if (k.a[i][j + 1] == k.a[i][j]) {
 72             v = k.a[i][j];
 73             if (TryMove1(k.a, i, j, 1)) {
 74               int d;
 75               if (j + 2 < 6 && k.a[i][j + 2] == v) d = 2;
 76               else d = 1;
 77               k.a[i][j] = 0, k.a[i][j + d + 1] = v;
 78               k.Get_Hash();
 79               if (st.find(k.Hash) == st.end()) {
 80                 k.Num++;
 81                 Q.push(k);
 82                 st.insert(k.Hash);
 83                 k.Num--;
 84               }
 85               k.a[i][j] = v, k.a[i][j + d + 1] = 0;
 86             }
 87             if (TryMove1(k.a, i, j, -1)) {
 88               int d;
 89               if (j + 2 < 6 && k.a[i][j + 2] == v) d = 2;
 90               else d = 1;
 91               k.a[i][j - 1] = v, k.a[i][j + d] = 0;
 92               k.Get_Hash();
 93               if (st.find(k.Hash) == st.end()) {
 94                 k.Num++;
 95                 Q.push(k);
 96                 st.insert(k.Hash);
 97                 k.Num--;
 98               }
 99               k.a[i][j - 1] = 0, k.a[i][j + d] = v;
100             }
101           } else {
102             v = k.a[i][j];
103             if (TryMove2(k.a, i, j, 1)) {
104               int d;
105               if (i + 2 < 6 && k.a[i + 2][j] == v) d = 2;
106               else d = 1;
107               k.a[i][j] = 0, k.a[i + d + 1][j] = v;
108               k.Get_Hash();
109               if (st.find(k.Hash) == st.end()) {
110                 k.Num++;
111                 Q.push(k);
112                 st.insert(k.Hash);
113                 k.Num--;
114               }
115               k.a[i][j] = v, k.a[i + d + 1][j] = 0;
116             }
117             if (TryMove2(k.a, i, j, -1)) {
118               int d;
119               if (i + 2 < 6 && k.a[i + 2][j] == v) d = 2;
120               else d = 1;
121               k.a[i - 1][j] = v, k.a[i + d][j] = 0;
122               k.Get_Hash();
123               if (st.find(k.Hash) == st.end()) {
124                 k.Num++;
125                 Q.push(k);
126                 st.insert(k.Hash);
127                 k.Num--;
128               }
129               k.a[i - 1][j] = 0, k.a[i + d][j] = v;
130             }
131           }
132         }
133       }
134     }
135   }
136   printf ("-1\n");
137 }
View Code

C Are They All Integers? Gym - 102460C  by myl

签到题,纯模拟,直接按照题意循环判断即可

 1 #include<cstdio>
 2 int a,b,c,d,i,m,n;
 3 int x[200]={0};
 4 
 5 int main()
 6 {
 7 scanf("%d",&a);
 8 for(i=1;i<=a;i++)
 9 {
10     scanf("%d",&x[i]);
11 }
12 b=1;
13 for(i=1;i<=a;i++)
14 {
15     for(m=i+1;m<=a;m++)
16     {
17         for(n=1;n<=a;n++)
18         {
19             if((i!=n)&&(m!=n))
20             {
21                 d=(x[m]-x[i])/x[n];
22                 if(x[n]*d!=x[m]-x[i]) b=0;
23             }
24         }
25     }
26 }
27 if(b==1) printf("yes\n");
28 else printf("no\n");
29 } 
View Code

D Tapioka Gym - 102460D  by wxh

水题,删除单词

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 char s[100], s1[100] = "bubble", s2[100] = "tapioka";
 4 int main() {
 5   int len;
 6   bool flag = 0;
 7   for (int i = 1; i <= 3; i++) {
 8     scanf ("%s", s);
 9     len = strlen(s);
10     if (len != 6 && len != 7) {
11       printf ("%s%c", s, " \n"[i == 3]), flag = 1;
12     } else if (len == 6) {
13       int j;
14       for (j = 0; j < len; j++) {
15         if (s[j] != s1[j]) break;
16       }
17       if (j != len) printf ("%s%c", s, " \n"[i == 3]), flag = 1;
18     } else {
19       int j;
20       for (j = 0; j < len; j++) {
21         if (s[j] != s2[j]) break;
22       }
23       if (j != len) printf ("%s%c", s, " \n"[i == 3]), flag = 1;
24     }
25   }
26   if (!flag) printf ("nothing\n");
27 }
View Code

E The League of swquence Designers Gym - 102460E  by myl

首先对于n,如果有可行解,那么肯定可以通过补0到1999个,所以无论n为多少,均构造出1999的数列

比较两段代码,最大的区别在于对于负数是否清0

构造的时候放一个负数,以1 -2开头,即可得出剩下的数和为a=(k+u)/2+1,u为之后的项

为了保证整除,对于k为偶数,开头加一个极大值-1000000

在放完所有a之后,用0补完,易证n<2000绝对有解

 1 #include<cstdio>
 2 int a,b,c,d,e,f,g,i,m,n,j,k,t;
 3 
 4 int main()
 5 {
 6 scanf("%d",&t);
 7 for(m=1;m<=t;m++)
 8 {
 9     scanf("%d%d",&k,&n);
10     if(n>=2000) printf("-1\n");
11     else
12     {
13         if(k&1)
14         {
15             a=(k+1997)/2+1;
16             printf("1999\n1 -2 ");
17             for(i=1;i<=1997;i++)
18             {
19                 if(a>1000000)
20                 {
21                     a-=1000000;
22                     printf("1000000 ");
23                 }
24                 else
25                 {
26                     if(a>0)
27                     {
28                         printf("%d ",a);
29                         a=0;
30                     }
31                     else printf("0 ");
32                 }
33             }
34             printf("\n");
35         }
36         else
37         {
38             a=(k+1996)/2+1;
39             printf("1999\n-1000000 1 -2 ");
40             for(i=1;i<=1996;i++)
41             {
42                 if(a>1000000)
43                 {
44                     a-=1000000;
45                     printf("1000000 ");
46                 }
47                 else
48                 {
49                     if(a>0)
50                     {
51                         printf("%d ",a);
52                         a=0;
53                     }
54                     else printf("0 ");
55                 }
56             }
57             printf("\n");
58         }
59     }
60     
61 }
62 }
View Code

H Mining a Gym - 102460H  by myl

构造题

亦或具有自反性 A XOR B XOR B = A XOR 0 = A

所以通过构造C = A XOR B 和B,反推出A的值

由等式可得,C=n(n+1),B=n+1

具体数学推导过程有点复杂,大致思路是利用不等式求解,其中个别情况需要特别考虑一下,但不影响结果

1 #include<cstdio>
2 long long a,n;
3 int main()
4 {
5 scanf("%lld",&n);
6 while(n--){scanf("%lld",&a);printf("%lld\n",a*a++^a);}
7 } 
View Code

I The Spectrum Gym - 102460I  by ltr

好恶心……

训练时写的是dfs+剪枝,具体操作是这样的:

首先,0和数列的最大值一定在原数列中,之后我们将输入的数列从大向小枚举,枚举他是原数列中的数还是最大值减原数列中的数得到的差,如果能够放到当前结果序列且与他们之间的差都能在原数列找到就放到当前结果序列里。

  1 #include<iostream>
  2 #include<cstdlib>
  3 #include<cstdio>
  4 #include<cstring>
  5 #include<algorithm>
  6 #include<queue>
  7 #define N 65
  8 using namespace std;
  9 int n;
 10 int A[N*N],cnt1[2000],cnt2[2000],cnt3[2000];
 11 int zz,ans[100005][N],q1[N];
 12 void dfs(int x)
 13 {
 14     if(ans[zz][0]==n)
 15     {
 16         zz++;
 17         for(int i=0;i<=n;i++)
 18         {
 19             ans[zz][i]=ans[zz-1][i];
 20         }
 21         return;
 22     }
 23     if(x==0)return;
 24     if(cnt2[A[x]])
 25     {
 26         cnt2[A[x]]--;
 27         dfs(x-1);
 28         cnt2[A[x]]++;
 29         return;
 30     }
 31     bool yx=1;
 32     for(int i=1;i<=ans[zz][0];i++)
 33     {
 34         cnt3[abs(A[x]-ans[zz][i])]++;
 35     }
 36     for(int i=1;i<=ans[zz][0];i++)
 37     {
 38         if(cnt3[abs(A[x]-ans[zz][i])]>cnt1[abs(A[x]-ans[zz][i])])
 39         {
 40             yx=0;
 41             break;
 42         }
 43     }
 44     for(int i=1;i<=ans[zz][0];i++)
 45     {
 46         cnt3[abs(A[x]-ans[zz][i])]=0;
 47     }
 48     if(yx)
 49     {
 50         for(int i=2;i<=ans[zz][0];i++)
 51         {
 52             cnt1[abs(A[x]-ans[zz][i])]--;
 53             cnt2[abs(A[x]-ans[zz][i])]++;
 54         }
 55         cnt1[A[x]]--;
 56         ans[zz][0]++;
 57         ans[zz][ans[zz][0]]=A[x];
 58     
 59         dfs(x-1);
 60         ans[zz][ans[zz][0]]=0;
 61         ans[zz][0]--;
 62         for(int i=2;i<=ans[zz][0];i++)
 63         {
 64             cnt1[abs(A[x]-ans[zz][i])]++;
 65             cnt2[abs(A[x]-ans[zz][i])]--;
 66         }
 67         cnt1[A[x]]++;
 68     }
 69     yx=1;
 70     int tmp=ans[zz][2]-A[x];
 71     for(int i=1;i<=ans[zz][0];i++)
 72     {
 73         cnt3[abs(tmp-ans[zz][i])]++;
 74     }
 75     for(int i=1;i<=ans[zz][0];i++)
 76     {
 77         if(cnt3[abs(tmp-ans[zz][i])]>cnt1[abs(tmp-ans[zz][i])])
 78         {
 79             yx=0;
 80             break;
 81         }
 82     }
 83     for(int i=1;i<=ans[zz][0];i++)
 84     {
 85         cnt3[abs(tmp-ans[zz][i])]=0;
 86     }
 87 
 88     if(yx)
 89     {
 90         for(int i=1;i<=ans[zz][0];i++)
 91         {
 92             cnt1[abs(tmp-ans[zz][i])]--;
 93             cnt2[abs(tmp-ans[zz][i])]++;
 94         }
 95         cnt2[A[x]]--;
 96         ans[zz][0]++;
 97         ans[zz][ans[zz][0]]=tmp;
 98     
 99         dfs(x-1);
100         ans[zz][ans[zz][0]]=0;
101         ans[zz][0]--;
102         for(int i=1;i<=ans[zz][0];i++)
103         {
104             cnt1[abs(tmp-ans[zz][i])]++;
105             cnt2[abs(tmp-ans[zz][i])]--;
106         }
107         cnt2[A[x]]++;
108     }
109 }
110 int main()
111 {
112     scanf("%d",&n);
113     for(int i=1;i<=n*(n-1)/2;i++)
114     {
115         scanf("%d",&A[i]);
116     }
117     if(A[n*(n-1)/2]>999)
118     {
119         printf("0\n");
120         return 0;
121     }
122     for(int i=1;i<=n*(n-1)/2;i++)
123     {
124         cnt1[A[i]]++;
125     }
126     zz++;
127     cnt1[A[n*(n-1)/2]]--;
128     ans[zz][0]=2;
129     ans[zz][1]=0;ans[zz][2]=A[n*(n-1)/2];
130     
131     dfs(n*(n-1)/2-1);
132     zz--;
133     for(int i=1;i<=zz;i++)
134     {
135         sort(ans[i]+1,ans[i]+n+1);
136     }
137     for(int i=1;i<=zz+5;i++)
138     {
139         for(int j=1;j<zz;j++)
140         {
141             for(int k=1;k<=n;k++)
142             {
143                 if(ans[j][k]>ans[j+1][k])
144                 {
145                     swap(ans[j],ans[j+1]);
146                     break;
147                 }
148                 else if(ans[j][k]<ans[j+1][k])
149                 {
150                     break;
151                 }
152                 if(k==n)
153                 {
154                     for(int l=j+1;l<zz;l++)
155                     {
156                         swap(ans[l],ans[l+1]);
157                     }
158                     zz--;
159                 }
160             }
161         }
162     }
163     printf("%d\n",zz);
164     for(int i=1;i<=zz;i++)
165     {
166         for(int j=1;j<=n;j++) printf("%d ",ans[i][j]);
167         printf("\n");
168     }
169     return 0;
170 }
View Code

然而,它T了……

后来经过查验,发现在原数列类似为等差数列的时候我的程序可以跑到2^n级别,大概原理就是某个数即可以是当前序列中的数,又可以是最大值减原数列里某个数的差,然后就复杂度爆炸。

那么我们应当怎么改呢?

我们经过冷静分析,发现当我们枚举到某个数的时候如果这个数在数列里出现次数-当前答案序列中各个数之差为在这个数的次数>2则一定不合法。这样我们就可以得到一个非常有效的剪枝。

之后我们分类讨论,当这个差值为1时,我们按照原来的做法枚举。当差值为2的时候就说明这个数如果合法就必须即时原数列里的数,又是最大值减原数列里某个数的差。这个时候我们就可以直接跳过去判断比这个数小的数了。复杂度大大减小。

但是,还有一个很重要的细节(虽说好像不写也能过)。

就是这个数正好是最大值的1/2,这种情况的话我们就按照他只出现一次处理就好了。举个例子:原数列为 0 1 2 3 4。即输入为

5

1 1 1 1 2 2 2 3 3 4

时,枚举到2的时候会发现4-2=2,这时候虽然2的差值为2,但是我们应当按照差值为1讨论。(具体看代码)

  1 #include<iostream>
  2 #include<cstdlib>
  3 #include<cstdio>
  4 #include<cstring>
  5 #include<algorithm>
  6 #include<queue>
  7 #define N 65
  8 using namespace std;
  9 int n;
 10 int A[N*N],cnt1[2000],cnt2[2000],cnt3[2000];
 11 int zz,ans[100005][N],q1[N];
 12 void dfs(int x)
 13 {
 14 
 15     if(ans[zz][0]==n)
 16     {
 17         zz++;
 18         for(int i=0;i<=n;i++)
 19         {
 20             ans[zz][i]=ans[zz-1][i];
 21         }
 22         return;
 23     }
 24     if(x==0)return;
 25     if(cnt2[A[x]])
 26     {
 27         cnt2[A[x]]--;
 28         dfs(x-1);
 29         cnt2[A[x]]++;
 30         return;
 31     }
 32     
 33     if(cnt1[A[x]]>2)return;
 34     if(cnt1[A[x]]==1||(cnt1[A[x]]==2&&ans[zz][2]-A[x]==A[x]))
 35     {
 36         bool yx=1;
 37         for(int i=1;i<=ans[zz][0];i++)
 38         {
 39             cnt3[abs(A[x]-ans[zz][i])]++;
 40         }
 41         for(int i=1;i<=ans[zz][0];i++)
 42         {
 43             if(cnt3[abs(A[x]-ans[zz][i])]>cnt1[abs(A[x]-ans[zz][i])])
 44             {
 45                 yx=0;
 46                 break;
 47             }
 48         }
 49         for(int i=1;i<=ans[zz][0];i++)
 50         {
 51             cnt3[abs(A[x]-ans[zz][i])]=0;
 52         }
 53         if(yx)
 54         {
 55             
 56             for(int i=2;i<=ans[zz][0];i++)
 57             {
 58                 cnt1[abs(A[x]-ans[zz][i])]--;
 59                 cnt2[abs(A[x]-ans[zz][i])]++;
 60             }
 61             cnt1[A[x]]--;
 62             ans[zz][0]++;
 63             ans[zz][ans[zz][0]]=A[x];
 64         
 65             dfs(x-1);
 66             ans[zz][ans[zz][0]]=0;
 67             ans[zz][0]--;
 68             for(int i=2;i<=ans[zz][0];i++)
 69             {
 70                 cnt1[abs(A[x]-ans[zz][i])]++;
 71                 cnt2[abs(A[x]-ans[zz][i])]--;
 72             }
 73             cnt1[A[x]]++;
 74         
 75         }
 76         if((cnt1[A[x]]==2&&ans[zz][2]-A[x]==A[x])) return;
 77         
 78         yx=1;
 79         int tmp=ans[zz][2]-A[x];
 80         for(int i=1;i<=ans[zz][0];i++)
 81         {
 82             cnt3[abs(tmp-ans[zz][i])]++;
 83         }
 84         for(int i=1;i<=ans[zz][0];i++)
 85         {
 86             if(cnt3[abs(tmp-ans[zz][i])]>cnt1[abs(tmp-ans[zz][i])])
 87             {
 88                 yx=0;
 89                 break;
 90             }
 91         }
 92     
 93         for(int i=1;i<=ans[zz][0];i++)
 94         {
 95             cnt3[abs(tmp-ans[zz][i])]=0;
 96         }
 97     
 98         if(yx)
 99         {
100             
101             for(int i=1;i<=ans[zz][0];i++)
102             {
103                 cnt1[abs(tmp-ans[zz][i])]--;
104                 cnt2[abs(tmp-ans[zz][i])]++;
105             }
106             cnt2[A[x]]--;
107             ans[zz][0]++;
108             ans[zz][ans[zz][0]]=tmp;
109         
110             dfs(x-1);
111             ans[zz][ans[zz][0]]=0;
112             ans[zz][0]--;
113             for(int i=1;i<=ans[zz][0];i++)
114             {
115                 cnt1[abs(tmp-ans[zz][i])]++;
116                 cnt2[abs(tmp-ans[zz][i])]--;
117             }
118             cnt2[A[x]]++;
119         }
120     }
121     else
122     {
123         bool yx=1;
124         for(int i=1;i<=ans[zz][0];i++)
125         {
126             cnt3[abs(A[x]-ans[zz][i])]++;
127         }
128         int tmp=ans[zz][2]-A[x];
129         cnt3[abs(A[x]-tmp)]++;
130         for(int i=1;i<=ans[zz][0];i++)
131         {
132             cnt3[abs(tmp-ans[zz][i])]++;
133         }
134         
135         for(int i=1;i<=ans[zz][0];i++)
136         {
137             if(cnt3[abs(A[x]-ans[zz][i])]>cnt1[abs(A[x]-ans[zz][i])])
138             {
139                 yx=0;
140                 break;
141             }
142         }
143         for(int i=1;i<=ans[zz][0];i++)
144         {
145             if(cnt3[abs(tmp-ans[zz][i])]>cnt1[abs(tmp-ans[zz][i])])
146             {
147                 yx=0;
148                 break;
149             }
150         }
151         
152         for(int i=1;i<=ans[zz][0];i++)
153         {
154             cnt3[abs(A[x]-ans[zz][i])]=0;
155         }
156         cnt3[abs(A[x]-tmp)]--;
157         for(int i=1;i<=ans[zz][0];i++)
158         {
159             cnt3[abs(tmp-ans[zz][i])]=0;
160         }
161         if(yx)
162         {
163             for(int i=2;i<=ans[zz][0];i++)
164             {
165                 cnt1[abs(A[x]-ans[zz][i])]--;
166                 cnt2[abs(A[x]-ans[zz][i])]++;
167             }
168             cnt1[A[x]]--;
169             ans[zz][0]++;
170             ans[zz][ans[zz][0]]=A[x];
171         
172             for(int i=1;i<=ans[zz][0];i++)
173             {
174                 cnt1[abs(tmp-ans[zz][i])]--;
175                 cnt2[abs(tmp-ans[zz][i])]++;
176             }
177             ans[zz][0]++;
178             ans[zz][ans[zz][0]]=tmp;
179             
180             dfs(x-1);
181             
182             ans[zz][ans[zz][0]]=0;
183             ans[zz][0]--;
184             for(int i=1;i<=ans[zz][0];i++)
185             {
186                 cnt1[abs(tmp-ans[zz][i])]++;
187                 cnt2[abs(tmp-ans[zz][i])]--;
188             }
189             
190             ans[zz][ans[zz][0]]=0;
191             ans[zz][0]--;
192             for(int i=2;i<=ans[zz][0];i++)
193             {
194                 cnt1[abs(A[x]-ans[zz][i])]++;
195                 cnt2[abs(A[x]-ans[zz][i])]--;
196             }
197             cnt1[A[x]]++;
198             
199             
200             
201         }
202     }
203 }
204 int main()
205 {
206 //    freopen("test.in","r",stdin);
207 //    freopen("1.out","w",stdout);
208     scanf("%d",&n);
209     for(int i=1;i<=n*(n-1)/2;i++)
210     {
211         scanf("%d",&A[i]);
212     }
213     if(A[n*(n-1)/2]>999)
214     {
215         printf("0\n");
216         return 0;
217     }
218     for(int i=1;i<=n*(n-1)/2;i++)
219     {
220         cnt1[A[i]]++;
221     }
222     zz++;
223     cnt1[A[n*(n-1)/2]]--;
224     ans[zz][0]=2;
225     ans[zz][1]=0;ans[zz][2]=A[n*(n-1)/2];
226     
227     dfs(n*(n-1)/2-1);
228     zz--;
229     for(int i=1;i<=zz;i++)
230     {
231         sort(ans[i]+1,ans[i]+n+1);
232     }
233     for(int i=1;i<=zz+5;i++)
234     {
235         for(int j=1;j<zz;j++)
236         {
237             for(int k=1;k<=n;k++)
238             {
239                 if(ans[j][k]>ans[j+1][k])
240                 {
241                     swap(ans[j],ans[j+1]);
242                     break;
243                 }
244                 else if(ans[j][k]<ans[j+1][k])
245                 {
246                     break;
247                 }
248                 if(k==n)
249                 {
250                     for(int l=j+1;l<zz;l++)
251                     {
252                         swap(ans[l],ans[l+1]);
253                     }
254                     zz--;
255                 }
256             }
257         }
258     }
259     printf("%d\n",zz);
260     for(int i=1;i<=zz;i++)
261     {
262         for(int j=1;j<=n;j++) printf("%d ",ans[i][j]);
263         printf("\n");
264     }
265     return 0;
266 }
View Code

J Automatic Control Machine Gym - 102460J  by wxh

二进制枚举, bitset 求与&然后判断1的个数。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 bitset<501> a[20], tp;
 4 char s[506];
 5 int main() {
 6   int T;
 7   scanf ("%d", &T);
 8   while (T--) {
 9     int n, m;
10     scanf ("%d%d", &n, &m);
11     for (int i = 1; i <= m; i++) {
12       scanf ("%s", s);
13       a[i].reset();
14       for (int j = 0; j < n; j++) a[i][j] = (s[j] == '1');
15     }
16     int N = 1 << m, num, ans = 0x3f3f3f3f;
17     for (int i = 0; i < N; i++) {
18       tp.reset();
19       num = 0;
20       for (int j = 1; j <= m; j++) {
21         if ((1 << (j - 1)) & i) {
22           tp |= a[j];
23           num ++;
24         }
25       }
26       if (tp.count() == n) ans = min(ans, num);
27     }
28     if (ans == 0x3f3f3f3f) ans = -1;
29     printf ("%d\n", ans);
30   }
31 }
View Code

K Length of Bundle Rope Gym - 102460K  by ltr

合并果子,每次贪心把最小的两个绑在一起即可

 1 #include<iostream>
 2 #include<cstdlib>
 3 #include<cstdio>
 4 #include<cstring>
 5 #include<algorithm>
 6 #include<queue>
 7 using namespace std;
 8 int T,n;
 9 priority_queue<int,vector<int>,greater<int > > q1;
10 int main()
11 {
12     scanf("%d",&T);
13     while(T--)
14     {
15         scanf("%d",&n);
16         long long ans=0;
17         while(!q1.empty()) q1.pop();
18         for(int i=1;i<=n;i++)
19         {
20             int x;
21             scanf("%d",&x);
22             q1.push(x);
23         }
24         while(q1.size()!=1)
25         {
26             int x=q1.top();q1.pop();
27             int y=q1.top();q1.pop();
28             ans+=x+y;
29             q1.push(x+y);
30         }
31         printf("%lld\n",ans);
32     }
33     return 0;
34 }
View Code

L Largest Quadrilateral Gym - 102460L  by myl

计算几何题

先求凸包

如果凸包是两个点,最大面积为0

如果凸包是三个点,四边形可定包括凸包的三个点,还需要再寻找一个点

如果凸包是四个点及以上,那么四边形肯定由凸包上的点构成,暴力枚举对角线,然后寻找对应的高的最大值,手动模拟后发现就是旋转卡壳

特别需要注意重点,不要去重,凸包保留重点,不要新增零点,这些操作都有可能导致错误

  1 #include<cstdio>
  2 #include<algorithm>
  3 using namespace std;
  4  
  5 struct xl
  6 {
  7     long long x,y;
  8 };
  9 
 10 long long a,b,c,d,e,f,g,i,m,n,T;
 11 long long w[100000]={0};
 12 long long ha,hb;
 13 xl x[100000],z;
 14 
 15 bool sx(xl j,xl k)
 16 {
 17 if((j.x==0)&&(k.x==0)) return j.y>k.y;
 18 if(j.x==0) return 0;
 19 if(k.x==0) return 1;
 20 if(j.x*k.y!=j.y*k.x) return j.x*k.y>j.y*k.x;
 21 return j.x<k.x;
 22 }
 23 
 24 long long mia(xl j,xl k,xl l)
 25 {
 26 return (j.x-l.x)*(k.y-l.y)-(j.y-l.y)*(k.x-l.x);
 27 }
 28 
 29 long long miaa(xl j,xl k,xl l)
 30 {
 31 long long t=mia(j,k,l);
 32 if(t<0) t=-t;
 33 return t;
 34 }
 35 
 36 long long qj(xl j,xl k,xl l)
 37 {
 38 long long h=mia(j,k,l);
 39 if(h>0) return 1;
 40 if(h<0) return 2;
 41 return 0;
 42 }
 43 
 44 void ma(long long &j,long long k,long long l)
 45 {
 46 if(k<0) k=-k;
 47 if(l<0) l=-l;
 48 if(j<k+l) j=k+l;
 49 }
 50 
 51 int main()
 52 {
 53 long long j,ka,kb,l,t;
 54 scanf("%lld",&T);
 55 for(t=1;t<=T;t++)
 56 {
 57     scanf("%lld",&n);
 58     scanf("%lld%lld",&x[1].x,&x[1].y);
 59     z=x[1];
 60     for(i=2;i<=n;i++)
 61     {
 62         scanf("%lld%lld",&x[i].x,&x[i].y);
 63         if(z.x>x[i].x) z=x[i];
 64         else
 65         {
 66             if((z.x==x[i].x)&&(z.y>x[i].y)) z=x[i];
 67         }
 68     }
 69     for(i=1;i<=n;i++)
 70     {
 71         x[i].x-=z.x;
 72         x[i].y-=z.y;
 73     }
 74     sort(x+1,x+n+1,sx);
 75     a=1;
 76     w[1]=0;
 77     for(i=1;i<=n;i++)
 78     {
 79         b=0;
 80         for(j=0;j<=n;j++)
 81         {
 82             if((j!=i)&&(j!=w[a])) b|=qj(x[j],x[i],x[w[a]]);
 83         }
 84         if(b<3)
 85         {
 86             a++;
 87             w[a]=i;
 88         }
 89     }
 90     ha=0;
 91     a--;
 92     if(a==3)
 93     {
 94         w[1]=n;
 95         for(i=1;i<=n;i++)
 96         {
 97             //printf("%lld %lld %lld %lld\n",i,x[i].x,x[i].y,w[i]);
 98             if((i!=w[1])&&(i!=w[2])&&(i!=w[3]))
 99             {
100                 ma(ha,mia(x[w[1]],x[w[2]],x[i]),mia(x[w[1]],x[w[3]],x[i]));
101                 ma(ha,mia(x[w[2]],x[w[1]],x[i]),mia(x[w[2]],x[w[3]],x[i]));
102                 ma(ha,mia(x[w[3]],x[w[1]],x[i]),mia(x[w[3]],x[w[2]],x[i]));
103             }
104         } 
105     }
106     else
107     {
108         for(i=1;i<=a;i++)
109         {
110             //printf("%lld %lld %lld\n",i,x[w[i]].x,x[w[i]].y);
111             ka=i+1; 
112             kb=i+3;
113             for(j=i+2;j<a;j++)
114             {
115                 if(kb<=j) kb=j+1;
116                 while((ka<j-1)&&(miaa(x[w[i]],x[w[ka]],x[w[j]])<=miaa(x[w[i]],x[w[ka+1]],x[w[j]]))) ka++;
117                 while((kb<a)&&(miaa(x[w[i]],x[w[j]],x[w[kb]])<=miaa(x[w[i]],x[w[j]],x[w[kb+1]]))) kb++;
118                 ma(ha,mia(x[w[i]],x[w[j]],x[w[ka]]),mia(x[w[i]],x[w[j]],x[w[kb]]));
119                 //printf("%lld %lld %lld %lld %lld\n",i,ka,j,kb,ha);
120             }
121         }
122     } 
123     if(ha%2==0) printf("%lld\n",ha/2);
124     else
125     {
126         printf("%lld",ha/2);
127         printf(".5\n");
128     }
129 }
130 } 
View Code
 

猜你喜欢

转载自www.cnblogs.com/liutianrui/p/12817055.html