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 }
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 }
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 }
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 }
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 }
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 }
然而,它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是否能够放入答案序列,不必再同时判断2和4-2了。
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 }
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 }
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 }
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 }