2015 Multi-University Training Contest 2
hdu 5301 Buildings
机智题,卡了好久,最后小坤纸上去敲过了。。做法:假设n < m,定义ans = (n + 1) / 2,ret = min(b, m - b + 1)。。当ret <= ans,对于当黑格子处于左上边的情况,就可以打横来覆盖左边的部分。当ret > ans的时候,就没办法打横覆盖了,ans = min(max(n - a, a - 1), ret)(注意a-1 != n-a)。最后还要特判一下黑格子处于中心的情况。
1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 #include<string> 5 #include<cstring> 6 #include<algorithm> 7 #include<set> 8 using namespace std; 9 10 11 #define inf 0x3f3f3f3f 12 #define eps 1e-9 13 #define FOR(i,s,t) for(int i = s; i < t; ++i ) 14 #define REP(i,s,t) for( int i = s; i <= t; ++i ) 15 #define pii pair<int,int> 16 #define MP make_pair 17 #define lson id << 1 , l , mid 18 #define rson id << 1 | 1 , mid + 1 , r 19 #define LL long long 20 #define ULL unsigned long long 21 #define N ( 500000 + 10 ) 22 #define M ( 1000000 + 10) 23 #define mod 1000000007 24 25 int main(){ 26 int a, n, m, b; 27 while(scanf("%d%d%d%d", &n, &m, &a, &b) != EOF){ 28 if(m <= 2 || n <= 2){ 29 puts("1"); continue; 30 } 31 if(n % 2 && m % 2 && a == (n + 1) / 2 && b == (m + 1) / 2){ 32 if(n == m) printf("%d\n", a - 1); 33 else printf("%d\n", min(b, a)); 34 continue; 35 } 36 if(n > m) 37 swap(n, m), swap(a, b); 38 int ans = (n + 1) / 2, ret = min(b, m - b + 1); 39 if(ret > ans && a - 1 != n - a) 40 ans = min(max(a - 1, n - a), ret); 41 printf("%d\n", ans); 42 } 43 return 0; 44 }
hdu 5302 Connect the Graph
构造题。当n >= 5时肯定有解。n为奇数,假设b2 = n, w2 = n,直接可以构造出1,2,3……n一个环满足b2 = n,构造1,3,5……2,4……1这样的环满足w2 = n。n为偶数,假设b2 = n, w2 = n,可以构造出1,2,3……n满足b2 = n,构造1,3,5……2,n,n-2,n-4……4满足w2 = n。对于b2 != n, w2 != n直接拆环就好了。对于n <= 4爆搜一下就好了。(实际上b0, b1, b2, w0, w1, w2都大于等于1,小于5的情况好像只有1,2,1,1,2,1才有解,其他无解,不需要搜)
1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 #include<string> 5 #include<cstring> 6 #include<algorithm> 7 #include<set> 8 using namespace std; 9 10 11 #define inf 0x3f3f3f3f 12 #define eps 1e-6 13 #define MP make_pair 14 #define LL long long 15 #define N 1000010 16 #define M 200020 17 #define mod 1000000007 18 19 int n, a[2][3], c[N]; 20 void work(int col){ 21 if(a[col][2] == n){ 22 for(int i = 1; i < n; ++i) 23 printf("%d %d %d\n", c[i], c[i+1], col); 24 printf("%d %d %d\n", c[n], c[1], col); 25 } 26 else{ 27 for(int i = 1; i <= a[col][2] + 1; ++i) 28 printf("%d %d %d\n", c[i], c[i+1], col); 29 for(int i = 3; i <= a[col][1]; i += 2) 30 printf("%d %d %d\n", c[a[col][2]+i], c[a[col][2]+i+1], col); 31 } 32 } 33 bool ok; 34 int cnt, uu[10], vv[10], col[10], use[5][2], ww[3], bb[3]; 35 void dfs(int cur){ 36 if(ok) return ; 37 if(cur == cnt){ 38 memset(use, 0, sizeof use); 39 ww[0] = ww[1] = ww[2] = bb[0] = bb[1] = bb[2] = 0; 40 for(int i = 0; i < cnt; ++i){ 41 if(col[i] == 0) 42 use[uu[i]][0]++, use[vv[i]][0]++; 43 if(col[i] == 1) 44 use[uu[i]][1]++, use[vv[i]][1]++; 45 } 46 for(int i = 1; i <= n; ++i){ 47 if(use[i][0] > 2 || use[i][1] > 2) return ; 48 ww[use[i][0]]++, bb[use[i][1]]++; 49 } 50 for(int i = 0; i < 3; ++i) 51 if(a[0][i] != ww[i] || a[1][i] != bb[i]) return ; 52 ok = 1; 53 printf("%d\n", a[0][1]/2 + a[0][2] + a[1][1]/2 + a[1][2]); 54 for(int i = 0; i < cnt; ++i) 55 if(col[i] == 0 || col[i] == 1) 56 printf("%d %d %d\n", uu[i], vv[i], col[i]); 57 return ; 58 } 59 col[cur] = 0; 60 dfs(cur + 1); 61 col[cur] = 1; 62 dfs(cur + 1); 63 col[cur] = 2; 64 dfs(cur + 1); 65 } 66 void gao(){ 67 cnt = 0; 68 ok = 0; 69 for(int i = 1; i <= n; ++i) 70 for(int j = i + 1; j <= n; ++j) 71 uu[cnt] = i, vv[cnt] = j, col[cnt++] = 0; 72 dfs(0); 73 if(!ok) puts("-1"); 74 } 75 int main(){ 76 //freopen("tt.txt", "r", stdin); 77 int cas; 78 scanf("%d", &cas); 79 while(cas--){ 80 scanf("%d%d%d%d%d%d", &a[0][0], &a[0][1], &a[0][2], &a[1][0], &a[1][1], &a[1][2]); 81 if(a[0][1] % 2 || a[1][1] % 2){ 82 puts("-1"); continue; 83 } 84 n = a[0][0] + a[0][1] + a[0][2]; 85 if(n <= 4){ 86 gao(); 87 continue; 88 } 89 printf("%d\n", a[0][1]/2 + a[0][2] + a[1][1]/2 + a[1][2]); 90 if(n % 2){ 91 for(int i = 1; i <= n; ++i) 92 c[i] = i; 93 work(0); 94 int cnt = 0; 95 for(int i = 1; i <= n; i += 2) 96 c[++cnt] = i; 97 for(int i = 2; i <= n; i += 2) 98 c[++cnt] = i; 99 work(1); 100 } 101 else{ 102 for(int i = 1; i <= n; ++i) 103 c[i] = i; 104 work(0); 105 int cnt = 0; 106 for(int i = 1; i <= n; i += 2) 107 c[++cnt] = i; 108 c[++cnt] = 2; 109 for(int i = n; i >= 4; i -= 2) 110 c[++cnt] = i; 111 work(1); 112 } 113 } 114 return 0; 115 }
hdu 5303 Delicious Apples
一道十分好的贪心题。最多只能绕一次环。
1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 #include<string> 5 #include<cstring> 6 #include<algorithm> 7 #include<set> 8 using namespace std; 9 10 11 #define inf 0x3f3f3f3f 12 #define eps 1e-9 13 #define FOR(i,s,t) for(int i = s; i < t; ++i ) 14 #define REP(i,s,t) for( int i = s; i <= t; ++i ) 15 #define pii pair<int,int> 16 #define MP make_pair 17 #define lson id << 1 , l , mid 18 #define rson id << 1 | 1 , mid + 1 , r 19 #define LL long long 20 #define ULL unsigned long long 21 #define N 1000010 22 #define M 200020 23 #define mod 1000000007 24 25 int a[N], a1[N], a2[N]; 26 LL p1[N], p2[N]; 27 int main(){ 28 int cas; 29 scanf("%d", &cas); 30 while(cas--){ 31 int L, n, k; 32 scanf("%d%d%d", &L, &n, &k); 33 int s = 0, mid = L / 2; 34 for(int i = 0; i < n; ++i){ 35 int pos, num; 36 scanf("%d%d", &pos, &num); 37 for(int j = 0; j < num; ++j) 38 a[++s] = pos; 39 } 40 k = min(s, k); 41 int c1 = 0, c2 = 0; 42 for(int i = 1; i <= s; ++i){ 43 if(a[i] <= mid) a1[++c1] = a[i]; 44 else a2[++c2] = L - a[i]; 45 } 46 sort(a1 + 1, a1 + 1 + c1); 47 sort(a2 + 1, a2 + 1 + c2); 48 for(int i = 1; i <= c1; ++i){ 49 if(i <= k) p1[i] = a1[i]; 50 else p1[i] = p1[i-k] + a1[i]; 51 } 52 for(int i = 1; i <= c2; ++i){ 53 if(i <= k) p2[i] = a2[i]; 54 else p2[i] = p2[i-k] + a2[i]; 55 } 56 LL ans = (p1[c1] + p2[c2]) * 2; 57 for(int i = 1; i <= c1 && i <= k; ++i){ 58 int lef = c1 - i, rig = c2 - (k - i); 59 ans = min(ans, (p1[lef] + p2[rig]) * 2 + L); 60 } 61 printf("%I64d\n", ans); 62 } 63 return 0; 64 }
hdu 5307 He is Flying
一道FFT的题目。用复数模板的FFT会因为精度误差而wa,又找了一个用快速数论变换的模板。中间有一个O(1)longlong内的乘法,我也不知道为什么这样算是对的。。
设所有的答案为 sigma(j - i +1) * X^(Sj - Si),拓展开来就可以得到题解的式子,可以用FFT求出所有正数的答案。ans0再另外处理一下。
(c++交上去是超时的,g++才能过)
1 #include <iostream> 2 #include <cstdio> 3 #include <cmath> 4 #include <string> 5 #include <cstring> 6 #include <algorithm> 7 #include <set> 8 using namespace std; 9 10 11 #define inf 0x3f3f3f3f 12 #define eps 1e-5 13 #define pii pair<int,int> 14 #define MP make_pair 15 #define LL long long 16 #define N 100010 17 #define M 200020 18 #define mod 1000000007 19 20 int read(){ 21 int ret = 0; char ch = getchar(); 22 while(ch < '0' || ch > '9') ch = getchar(); 23 while(ch >= '0' && ch <= '9') ret = ret * 10 + ch - '0', ch = getchar(); 24 return ret; 25 } 26 void out(LL x){ 27 if(x > 9) out(x / 10); 28 putchar(x % 10 + '0'); 29 } 30 const LL P = 50000000001507329LL, NN = 1LL<<18, G = 3; 31 32 LL Mul(LL x, LL y){ 33 return (x * y - (LL)(x / (long double)P * y + 1e-3) * P + P) % P; 34 } 35 LL qpow(LL x, LL k, LL m){ 36 x %= m, k %= m; 37 LL ret = 1; 38 while(k){ 39 if(k & 1) ret = Mul(ret, x); 40 x = Mul(x, x); 41 k >>= 1; 42 } 43 return ret; 44 } 45 LL wn[25]; 46 void getWn(){ 47 for(int i = 0; i <= 20; ++i){ 48 int t = 1 << i; 49 wn[i] = qpow(G, (P - 1) / t, P); 50 } 51 } 52 void Rader(LL *a, int len){ 53 int k; 54 for(int i = 1, j = len / 2; i < len - 1; ++i){ 55 if(i < j) swap(a[i], a[j]); 56 k = len / 2; 57 while(j >= k) j -= k, k /= 2; 58 if(j < k) j += k; 59 } 60 } 61 void FFT(LL *a, int len, int on){ 62 Rader(a, len); 63 int id = 0; 64 for(int h = 2; h <= len; h <<= 1){ 65 id++; 66 for(int j = 0; j < len; j += h){ 67 LL w = 1; 68 for(int k = j; k < j + h / 2; ++k){ 69 LL u = a[k]; 70 LL t = Mul(a[k+h/2], w); 71 a[k] = u + t; 72 if(a[k] >= P) a[k] -= P; 73 a[k+h/2] = u - t + P; 74 if(a[k+h/2] >= P) a[k+h/2] -= P; 75 w = Mul(w, wn[id]); 76 } 77 } 78 } 79 if(on == -1){ 80 for(int i = 1; i < len / 2; ++i) 81 swap(a[i], a[len-i]); 82 LL inv = qpow(len, P-2, P); 83 for(int i = 0; i < len; ++i) 84 a[i] = Mul(a[i], inv); 85 } 86 } 87 void Conv(LL *a, LL *b, int n){ 88 FFT(a, n, 1); 89 FFT(b, n, 1); 90 for(int i = 0; i < n; ++i) 91 a[i] = Mul(a[i], b[i]); 92 FFT(a, n, -1); 93 } 94 LL s[N], p[N], a[M], b[M], ans[M]; 95 int main(){ 96 getWn(); 97 int cas; 98 scanf("%d", &cas); 99 for(int i = 1; i <= N / 2; ++i) 100 p[i] = p[i-1] + (LL)(i + 1) * (LL)i / 2; 101 while(cas--){ 102 int n; 103 scanf("%d", &n); 104 for(int i = 1; i <= n; ++i){ 105 int x; 106 x = read(); 107 s[i] = s[i-1] + x; 108 } 109 LL ans0 = 0; 110 int pre = s[0], cnt = 0; 111 s[n+1] = -1; 112 for(int i = 1; i <= n + 1; ++i){ 113 if(s[i] == pre) 114 cnt++; 115 else 116 ans0 += p[cnt], cnt = 0, pre = s[i]; 117 } 118 int len = 1; 119 while(len <= s[n] * 2) len <<= 1; 120 memset(a, 0, sizeof a); 121 memset(b, 0, sizeof b); 122 for(int i = 1; i <= n; ++i) 123 a[s[i]] += i, b[s[n] - s[i-1]]++; 124 Conv(a, b, len); 125 for(int i = 0; i < len; ++i) 126 ans[i] = a[i]; 127 memset(a, 0, sizeof a); 128 memset(b, 0, sizeof b); 129 for(int i = 1; i <= n; ++i) 130 a[s[i]]++, b[s[n] - s[i-1]] += i-1; 131 Conv(a, b, len); 132 for(int i = 0; i < len; ++i){ 133 ans[i] = ans[i] - a[i]; 134 if(ans[i] < 0) ans[i] += P; 135 if(ans[i] >= P) ans[i] -= P; 136 } 137 printf("%I64d\n", ans0); 138 for(int i = 1; i <= s[n]; ++i) 139 out(ans[i+s[n]]), puts(""); 140 } 141 return 0; 142 }
hdu 5308 I Wanna Become A 24-Point Master
算24点。傻逼了,7个7竟然没算出来。。贴纬哥的代码
1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 #include<string> 5 #include<cstring> 6 #include<algorithm> 7 #include<set> 8 using namespace std; 9 10 11 #define inf 0x3f3f3f3f 12 #define eps 1e-9 13 #define FOR(i,s,t) for(int i = s; i < t; ++i ) 14 #define REP(i,s,t) for( int i = s; i <= t; ++i ) 15 #define pii pair<int,int> 16 #define MP make_pair 17 #define lson id << 1 , l , mid 18 #define rson id << 1 | 1 , mid + 1 , r 19 #define LL long long 20 #define ULL unsigned long long 21 #define N ( 500000 + 10 ) 22 #define M ( 1000000 + 10) 23 #define mod 1000000007 24 25 26 void out ( int n ) 27 { 28 29 if( n <= 3 ) { 30 puts("-1"); 31 return ; 32 } 33 if( n == 4 ) { 34 string s = "1 * 2\n3 + 4\n5 + 6"; 35 cout<<s<<endl; 36 } 37 if( n == 5 ) { 38 puts("1 / 2"); 39 puts("6 / 3"); 40 puts("4 - 7"); 41 puts("5 * 8"); 42 } 43 if( n == 6 ) { 44 puts("1 - 2"); 45 printf("%d + %d\n%d + %d\n", 3, 4, 5, 6 ); 46 for( int i = 7; i < 11; i+=2 ) 47 printf("%d + %d\n", i, i + 1 ); 48 } 49 if( n == 7 ) { 50 puts("1 * 2"); // 8 = 49 51 puts("3 / 4"); // 9 = 1 52 puts("8 - 9"); // 10 = 48 53 puts("5 + 6"); 54 puts("10 / 11"); 55 puts("12 * 7"); } 56 if( n == 8 ) { 57 puts("1 + 2"); 58 puts("9 + 3"); // 10 = 24 59 puts("4 - 5"); // 11 = 0 60 int i = 6, j = 11; 61 for( ; i <= 8; ++i ) 62 printf("%d * %d\n", i, j ++ ); 63 printf("%d + %d\n",j, 10); 64 } 65 if( n == 9 ) { 66 for( int i = 1; i <= 6; i+=2 ) 67 printf("%d / %d\n", i, i + 1 ); 68 puts("7 + 8"); 69 printf("%d + %d\n",13, 9 ); //a[14] = 27 70 int i = 14, j = 10; 71 while( j <= 12 ) printf("%d - %d\n", i++, j++ ); 72 } 73 if( n == 10 ) 74 { 75 int k = 10; 76 for( int i = 1; i <= 8; i += 2 ) 77 printf("%d / %d\n", i, i + 1 ), ++k; 78 printf("%d + %d\n", 9, 10 );++k; 79 int j = 11; 80 while( k < 19 ) 81 printf("%d + %d\n", k++, j++); 82 } 83 if( n == 11 ) { 84 puts("1 + 2"); // 12 85 puts("12 / 3"); // 13 86 puts("4 + 5"); // 14 87 puts("6 - 7"); // 15 88 int j = 15; 89 for( int i = 8; i <= 11; ++i ) 90 printf("%d * %d\n", j++, i ); 91 for( int i = 13; i <= 14; ++i ) 92 printf("%d + %d\n", i, j ++); 93 } 94 if( n == 12 ) { 95 puts("1 + 2"); // 13 96 puts("3 - 4"); // 14 97 int j = 14; 98 for( int i = 5; i <= 12; ++i ) 99 printf("%d * %d\n", i, j ++ ); 100 printf("%d + %d\n", j, 13 ); 101 } 102 if(n == 13 ) { 103 puts("1 + 2"); 104 puts("3 + 4" ); 105 puts("15 / 5");//16 106 puts("14 - 16"); // 17 = 24; 107 puts("6 - 7"); // 18 108 int j = 18; 109 for( int i = 8 ; i <= 13; i ++ ) 110 printf("%d * %d\n", j++, i ); 111 printf("%d + %d\n", j , 17 ); 112 } 113 if( n ==15 ) { 114 puts("1 + 2"); //16 30 115 puts("16 / 3"); // 17 2 116 puts("4 + 5"); // 18 2n 117 puts("18 / 6"); // 19 2 118 puts("7 / 8"); // 20 1; 119 puts("20 + 19"); // 21 3 120 puts("17 * 21"); // 22 6; 121 puts("9 + 10"); // 23 30; 122 puts("23 - 22"); // 24 = 24 123 puts("11 - 12"); // 25 = 0; 124 int j = 25; 125 for( int i = 13; i <= 15; ++i ) 126 printf("%d * %d\n", i, j++ ); 127 printf("%d + %d\n", j, 24 ); 128 } 129 130 131 } 132 133 char s[100]; 134 int A[1000]; 135 bool vis[1000]; 136 void check( ) 137 { 138 int n; 139 while( cin>>n ) { 140 getchar(); 141 for( int i = 1; i <= n; ++i ) 142 A[i] = n; 143 memset( vis, 0, sizeof( vis )); 144 bool e = 1; 145 int k = n + 1; 146 for( int z = 1; z <= n - 1; ++z ) { 147 gets(s); 148 int len = strlen( s ); 149 int a = 0, b = 0; 150 int i; 151 for( i = 0; i < len; ++i ) { 152 if( '0'<= s[i] && s[i] <= '9') 153 a = a * 10 + s[i] - '0'; 154 else break; 155 } 156 int j = i + 1; 157 for( i = i + 3; i < len; ++i ) 158 b = b * 10 + s[i] - '0'; 159 160 if( vis[a] ) e = 0; 161 if( vis[b] ) e = 0; 162 if( a >= k || b >= k ) e = 0; 163 vis[a] = vis[b] = 1; 164 if( s[j] == '+') A[k++] = A[a] + A[b]; 165 if( s[j] == '-') A[k++] = A[a] - A[b]; 166 if( s[j] == '*' ) A[k++] = A[a] * A[b]; 167 if( s[j] == '/') A[k++] = A[a] / A[b]; 168 } 169 for( int i = 1; i <= 2 * n -1; ++i ) 170 printf("%d ", A[i] ); 171 puts(""); 172 173 if( e && A[2*n-1] == 24 ) 174 puts("YES"); 175 else { 176 printf("%d NO\n", n ); 177 } 178 } 179 } 180 int main ( ) 181 { 182 183 int n; 184 185 186 while(~scanf("%d", &n ) ) { 187 if( n >= 14 && n != 15 ) { 188 for( int i = 1; i <= 7; i += 2 ) 189 printf("%d + %d\n", i, i + 1 ); 190 for( int i = 1; i <= 4; ++i ) 191 printf("%d / %d\n", n+i, i + 8 ); 192 printf("%d / %d\n", 13, 14 );// n + 9 == 1 193 194 printf("%d + %d\n", n + 5, n + 6 ); // a[n+10] = 4 195 printf("%d + %d\n", n + 7, n + 9 ); // a[n+11] = 3 196 printf("%d * %d\n", n + 11, n + 8 ); // a[n+12] = 6; 197 198 printf("%d * %d\n", n+10, n + 12 ); // a[n+13] = 24; 199 200 if( n == 14 ) continue; 201 printf("%d - %d\n", 15, 16 ); //a[n+14] = 0; 202 int j = n + 14; 203 for( int i = 17; i <= n; ++i ) 204 printf("%d * %d\n", i, j++ ); 205 printf("%d + %d\n", j, n + 13 ); 206 207 } 208 else out( n ); 209 } 210 211 }