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 }

 

后记

机房与机房间的差距

posted @ 2018-10-14 21:27  AntiQuality  阅读(203)  评论(0编辑  收藏  举报