Codeforces Round #516 Div2 (A~D)By cellur925

比赛传送门

A. Make a triangle!

题目大意:给你三根木棒,选出其中一根木棒增加它的长度,使构成三角形,问增加的长度最小是多少。

思路:签到题,根据样例/三角形性质不难发现,答案就是最长边减剩下两边之和加一。

 1 #include<cstdio>
 2 #include<algorithm>
 3 
 4 using namespace std;
 5 
 6 int seq[5];
 7 
 8 int main()
 9 {
10     for(int i=1;i<=3;i++) scanf("%d",&seq[i]);
11     sort(seq+1,seq+1+3);
12     if(seq[1]+seq[2]>seq[3]){printf("0");return 0;}
13     printf("%d",seq[3]-(seq[1]+seq[2])+1);
14     return 0;
15 }
A

B. Equations of Mathematical Magic

题目大意:多组数据,每组给你一个$a$,求$a-(a xor x)-x=0$方程的解的个数。

思路:开始发现答案范围在0~a用二进制表示的几位最大的数(即a在二进制下有x位,则上限为$2^x$。)于是打了个200的表,发现与a的二进制表示下有多少个1有关。但是验证这个想法的时候,实现出锅了,于是耽搁了好久...后来发现自己的想法是正确的。设a的二进制表示下有x个1,那么最终答案就是$2^x$。

 1 #include<cstdio>
 2 #include<algorithm>
 3 
 4 using namespace std;
 5 
 6 int T,a;
 7 
 8 int work(int x)
 9 {
10     int tmp=x,cnt=0;
11     while(tmp)
12     {
13         if(tmp%2==1) cnt++;
14         tmp/=2;
15     }
16     return cnt;
17 }
18 
19 int main()
20 {
21     scanf("%d",&T);
22     while(T--)
23     {
24         scanf("%d",&a);
25         int hu=work(a);
26         int ans=(1<<hu);
27         printf("%d\n",ans);
28     }
29     return 0;
30 }
B

C. Oh Those Palindromes

题目大意:给你一个字符串,你可以对其中的字符进行任意调换顺序,求变换后的一个字符串,使得新字符串有最多的回文子串。(注意,可能有多个,输出一个即可)

思路:想这个题一个多小时都没搞出来...结束后发现核心代码只有5行??被样例蒙蔽了...感觉还需要不同的字母间匹配什么的,其实只需要把字符串中相同的字符排在一起就行了。

One possible solution is just to sort the string.

Why so?

Note that each palindrome have equal character at their ends. Suppose this character is cc with xx number of occurences. Then there are at most x(x+1)/2 palindromes with this character.

So we have a clear upper bound on answer. It is easy to see, that the sorted string fulfills that bound and hence(因此) it is the optimal(理想的) answer.(官方题解)

至于为什么是x(x+1)/2....

Since 'c' has x number of occurrences, thus palindrome with 'c' are x , palindrome which are 'cc' are x-1 , palindrome which are 'ccc' are x-2 and so on.

so we get x+x-1+....+2+1 = x(x+1)/2 for 'c' which has frequency x.

简单的加法原理==。

唉被这道题坑了,于是我现在就是真·pupil了...

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<iostream>
 4 
 5 using namespace std;
 6 
 7 int n;
 8 string x;
 9 
10 int main()
11 {
12     scanf("%d",&n);
13     cin>>x;
14     sort(x.begin(),x.end());
15     cout<<x;
16     return 0;
17 }
C

D. Labyrinth

题目大意:在一个棋盘中,你从起点出发,问能到达多少点,但有向左走不超过$x$步,向右走不超过$y$步的限制。

思路1:如果没有那个限制,就是简单的$bfs$了。然后看了一位Chinese大神写的,每次我们要想使答案最优,一定要尽量走左右移动少的。

于是就可以用优先队列维护$l+r$少的状态,进行$bfs$。

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<queue>
 4 
 5 using namespace std;
 6 
 7 int n,m,r,c,llim,rlim,ans;
 8 int dx[10]={0,-1,0,1,0};
 9 int dy[10]={0,0,1,0,-1};
10 bool vis[3000][3000];
11 char tmp[3000],mapp[3000][3000];
12 struct node{
13     int x,y,l,r;
14 };
15 bool operator < (const node &x,const node &y)
16 {
17     return x.l+x.r>y.l+y.r;
18 }
19 
20 bool valid(int x,int y)
21 {
22     if(x>=1&&x<=n&&y>=1&&y<=m) return 1;
23     return 0;
24 }
25 
26 void bfs(int r,int c)
27 {
28     priority_queue<node>q;
29     node p;
30     p.x=r,p.y=c,p.l=0,p.r=0;
31     q.push(p);vis[r][c]=1;
32     while(!q.empty())
33     {
34         node u=q.top();q.pop();
35         for(int i=1;i<=4;i++)
36         {
37             int nowx=u.x+dx[i];
38             int nowy=u.y+dy[i];
39             int nowl=u.l+(dy[i]==-1);
40             int nowr=u.r+(dy[i]==1);
41             if(!valid(nowx,nowy)||mapp[nowx][nowy]=='*') continue;
42             if(nowl>llim||nowr>rlim) continue;
43             if(!vis[nowx][nowy])
44             {
45                 vis[nowx][nowy]=1;
46                 node tmp;
47                 tmp.x=nowx,tmp.y=nowy;
48                 tmp.l=nowl,tmp.r=nowr;
49                 q.push(tmp);
50             }
51         }
52     }
53 }
54 
55 int main()
56 {
57     scanf("%d%d",&n,&m);
58     scanf("%d%d",&r,&c);
59     scanf("%d%d",&llim,&rlim);
60     for(int i=1;i<=n;i++)
61     {
62         scanf("%s",tmp+1);
63         for(int j=1;j<=m;j++) mapp[i][j]=tmp[j];
64     }
65     bfs(r,c);
66     for(int i=1;i<=n;i++)
67         for(int j=1;j<=m;j++)
68             if(vis[i][j]) ans++;
69     printf("%d",ans);
70     return 0;
71 }
D

还有一个很妙的想法:https://www.cnblogs.com/zwfymqz/p/9789569.html

 

这次是真惨..C题没做出来,成功成为了pupil....

话说我怎么这么菜啊

posted @ 2018-10-16 18:20  cellur925&Chemist  阅读(180)  评论(0编辑  收藏  举报