Codeforces Round #516 (Div. 2, by Moscow Team Olympiad)
FST;心态凉凉;没有前记
A. Make a triangle!
就是这样
1 #include<bits/stdc++.h> 2 3 int a[5]; 4 5 int read() 6 { 7 char ch = getchar(); 8 int num = 0; 9 bool fl = 0; 10 for (; !isdigit(ch); ch=getchar()) 11 if (ch=='-') fl = 1; 12 for (; isdigit(ch); ch=getchar()) 13 num = (num<<1)+(num<<3)+ch-48; 14 if (fl) num = -num; 15 return num; 16 } 17 int main() 18 { 19 for (int i=1; i<=3; i++) a[i] = read(); 20 std::sort(a+1, a+4); 21 int ans = 1+a[3]-a[1]-a[2]; 22 printf("%d\n",ans > 0?ans:0); 23 return 0; 24 }
B. Equations of Mathematical Magic
反正就是考虑xor性质
然后拆开
1 #include<bits/stdc++.h> 2 3 int n,T,cnt; 4 5 int read() 6 { 7 char ch = getchar(); 8 int num = 0; 9 bool fl = 0; 10 for (; !isdigit(ch); ch=getchar()) 11 if (ch=='-') fl = 1; 12 for (; isdigit(ch); ch=getchar()) 13 num = (num<<1)+(num<<3)+ch-48; 14 if (fl) num = -num; 15 return num; 16 } 17 int main() 18 { 19 T = read(); 20 while (T--) 21 { 22 int n = read(); 23 cnt = 0; 24 while (n) 25 { 26 cnt++; 27 n = n&(n-1); 28 } 29 printf("%d\n",1<<cnt); 30 } 31 return 0; 32 }
【构造】C. Oh Those Palindromes
题意:重排一个字符串,使回文子串最多。
那么一种想法就是尽可能构造长的回文串,然后把它们拼接起来。
所以可以把相同的字母都放在一起。写得有点冗长了,直接sort就好了。
1 #include<bits/stdc++.h> 2 3 int n,t[31]; 4 char s[100035]; 5 6 int read() 7 { 8 char ch = getchar(); 9 int num = 0; 10 bool fl = 0; 11 for (; !isdigit(ch); ch=getchar()) 12 if (ch=='-') fl = 1; 13 for (; isdigit(ch); ch=getchar()) 14 num = (num<<1)+(num<<3)+ch-48; 15 if (fl) num = -num; 16 return num; 17 } 18 int main() 19 { 20 scanf("%d%s",&n,s+1); 21 for (int i=1; i<=n; i++) t[s[i]-'a']++; 22 for (int i=0; i<=25; i++) 23 for (int j=1; j<=t[i]; j++) 24 putchar('a'+i); 25 puts(""); 26 return 0; 27 }
【记忆化BFS】D. Labyrinth
全机房不知道哪来的莫名自信,全都写了裸的BFS交上去过了pretest(话说CF不是要求pretest要包含尽可能多情况吗?……)
所以没心情写了。
upd:坑还是填一下吧……平心而论题还不错,考查内容基础又不偏门,写挂是自己的锅
#include<bits/stdc++.h> const int maxn = 2035; const int dx[] = {0, 1, 0, -1, 0}; const int dy[] = {0, 0, 1, 0, -1}; struct node { int a,b,c,d; node(int a1=0, int a2=0, int a3=0, int a4=0):a(a1),b(a2),c(a3),d(a4) {} }; int n,m,r,c,x,y,ans; int mp[maxn][maxn]; int lb1[maxn][maxn],lb2[maxn][maxn]; bool vis[maxn][maxn]; std::queue<node> q; int read() { char ch = getchar(); int num = 0; bool fl = 0; for (; !isdigit(ch); ch=getchar()) if (ch=='-') fl = 1; for (; isdigit(ch); ch=getchar()) num = (num<<1)+(num<<3)+ch-48; if (fl) num = -num; return num; } inline void Max(int &a, int b){a = a > b?a:b;} int get() { char ch = getchar(); while (ch!='.'&&ch!='*') ch = getchar(); return ch=='.'; } bool legal(int x, int y, int a, int b) { return x >= 1&&x <= n&&y >= 1&&y <= m&&mp[x][y]&&(lb1[x][y] < a||lb2[x][y] < b); } int main() { memset(lb1, -1, sizeof lb1); memset(lb2, -1, sizeof lb2); n = read(), m = read(), r = read(), c = read(), x = read(), y = read(); for (int i=1; i<=n; i++) for (int j=1; j<=m; j++) mp[i][j] = get(); q.push(node(r, c, x, y)); vis[r][c] = 1, lb1[r][c] = x, lb2[r][c] = y; while (q.size()) { node now = q.front(); q.pop(); int x = now.a, y = now.b, l = now.c, r = now.d; if (legal(x+1, y, l, r)) Max(lb1[x+1][y], l), Max(lb2[x+1][y], r), vis[x+1][y] = 1, q.push(node(x+1, y, l, r)); if (legal(x-1, y, l, r)) Max(lb1[x-1][y], l), Max(lb2[x-1][y], r), vis[x-1][y] = 1, q.push(node(x-1, y, l, r)); if (legal(x, y+1, l, r-1)&&r) Max(lb1[x][y+1], l), Max(lb2[x][y+1], r-1), vis[x][y+1] = 1, q.push(node(x, y+1, l, r-1)); if (legal(x, y-1, l-1, r)&&l) Max(lb1[x][y-1], l-1), Max(lb2[x][y-1], r), vis[x][y-1] = 1, q.push(node(x, y-1, l-1, r)); } for (int i=1; i<=n; i++) for (int j=1; j<=m; j++) if (vis[i][j]) ans++; printf("%d\n",ans); return 0; }
(代码框好像挂了?)
【构造】E. Dwarves, Hats and Extrasensory Abilities
二分的大致思路对了。然后我的做法是n==30特判,枚举对角线。
然而细节挂了。
也没心情写了。
upd:有趣的构造题,有一些细节需要注意特判。
可以想到一种做法:将二维问题转成x轴上的问题,那么每一次询问$(mid,0)$的颜色,以此移动左右端点。但是这样在最坏情况下,只能通过n=29的数据。
于是利用二维性质,首先询问$(0,0)$的颜色,称为基准色;之后二分每次询问$(mid,mid)$的颜色是否等于基准色,以此移动端点。因为最后可能会出现两个询问点x坐标相邻的情况,所以切割线就定为$(mid-1,mid)--(mid,mid-1)$。
需要注意的是,由于这种做法将$(0,0)$固定,所以二分时候$r=mid$.
1 #include<bits/stdc++.h> 2 const int INF = 1000000000; 3 4 int n,l,r,mid,c; 5 char s[103],T[103]; 6 7 int read() 8 { 9 char ch = getchar(); 10 int num = 0; 11 bool fl = 0; 12 for (; !isdigit(ch); ch=getchar()) 13 if (ch=='-') fl = 1; 14 for (; isdigit(ch); ch=getchar()) 15 num = (num<<1)+(num<<3)+ch-48; 16 if (fl) num = -num; 17 return num; 18 } 19 void cl() 20 { 21 fflush(stdout); 22 } 23 int main() 24 { 25 n = read(); 26 if (n==1){ 27 printf("%d %d\n",0,0), cl(); 28 puts("1 0 0 1"); 29 return 0; 30 } 31 printf("%d %d\n",0,0), cl(); 32 scanf("%s",T); 33 l = 1, r = INF; 34 for (int i=1; i<n; i++) 35 { 36 mid = (l+r)>>1; 37 printf("%d %d\n",mid,mid), cl(); 38 scanf("%s",s); 39 if (s[0]==T[0]) c = 0; 40 else c = 1; 41 if (c) r = mid; 42 else l = mid+1; 43 } 44 mid = (l+r)>>1; 45 printf("%d %d %d %d\n",mid-1,mid,mid,mid-1), cl(); 46 return 0; 47 }
后记
机房与机房间的差距