2019.11.16工作坊比赛题解
Posted algonote
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2019.11.16工作坊比赛题解相关的知识,希望对你有一定的参考价值。
A
https://vjudge.net/contest/343173#problem/A
把所有的长条按长度进行排序
在从左到右扫一遍能构造出的矩形,其中所有矩形中Max(Width,Height)的最大值即为能够造出的最大正方形的边长
#include <cstdio> #include <algorithm> using namespace std; int t,n,a[1001],ans; bool cmp(int a,int b) { return a>b; } int main() { scanf("%d",&t); while(t--) { ans=0; scanf("%d",&n); for (int i=1;i<=n;i++) scanf("%d",&a[i]); sort(a+1,a+n+1,cmp); for (int i=1;i<=n;i++) ans=max(ans,min(i,a[i])); printf("%d ",ans); } }
B
https://vjudge.net/contest/343173#problem/B
可行的只有三种情况,即a==b,a+1==b,a==9&&b==1,针对这三种情况各写一个可行解的模板即可
#include <cstdio> #include <algorithm> using namespace std; int a,b; int main() { scanf("%d%d",&a,&b); if (b==a) printf("%d0 %d1 ",a,b); else if (b==a+1) printf("%d %d ",a,b); else if (b==1&&a==9) printf("%d %d0 ",a,b); else printf("-1 "); }
C
https://vjudge.net/contest/343173#problem/C
能力值相邻的人不能分配到同一组
考虑到如果把所有偶数能力值分配在一组,把所有奇数能力值分配在一组,肯定满足题目要求,所以可以得出组数一定<=2
那么只要把所有人按能力值排序,从左到右扫一次判断这些人能不能在同一组就知道答案是1还是2了
#include <cstdio> #include <algorithm> using namespace std; int q,n,a[101],ans; int main() { scanf("%d",&q); while(q--) { ans=1; scanf("%d",&n); for (int i=1;i<=n;i++) scanf("%d",&a[i]); sort(a+1,a+1+n); for (int i=1;i<n;i++) if (a[i]==a[i+1]-1) ans=2; printf("%d ",ans); } }
D
https://vjudge.net/contest/343173#problem/D
求满足n=(2^a1+p)+(2^a2+p)+...+(2^ak+p)的k的最小值
对等式进行变形
n-p*k=2*a1+2*a2+...+2*ak
把n-p*k分解为若干个2^ai的和
对于1可以分解为1,最多一种分法
对于10可以分解为10或1+1,最多两种分法
对于100可以分解为100或10+10或10+1+1或1+1+1+1,最多四种分法
所以组合起来,对于n-p*k,最少分解为countbit(n-p*k)个2^ai的和,最多分解为n-p*k个2^ai的和
已知countbit<=32所以如果对i=33满足,那么对i=32肯定也满足,所以答案小于等于32,这样就减小了搜索的范围
#include <cstdio> int n,p,b,ans=-1; int countbit(int x) { int r=0; while(x) { r+=x%2; x>>=1; } return r; } int main() { scanf("%d%d",&n,&p); for (int i=0;i<=32;i++) { int t=n-p*i; if (ans==-1&&t>=i&&i>=countbit(t)) ans=i; } printf("%d",ans); }
E
https://vjudge.net/contest/343173#problem/E
田忌赛马,尽可能多赢的就可以了
对于赢不了的情况不要着急做决定,应该先跳过,否则可能会浪费后面本来能赢的机会
等所有能赢的情况都统计完了之后,再决定之前跳过的情况是输还是平手
#include <cstdio> int t,n,a,b,c; char s,ans[101],win; int main() { scanf("%d",&t); while(t--) { win=0; scanf("%d%d%d%d",&n,&a,&b,&c); for (int i=1;i<=n;i++) ans[i]=0; scanf("%c",&s); for (int i=1;i<=n;i++) { scanf("%c",&s); if (s==‘R‘&&b>0) {ans[i]=‘P‘;b--;win++;} if (s==‘P‘&&c>0) {ans[i]=‘S‘;c--;win++;} if (s==‘S‘&&a>0) {ans[i]=‘R‘;a--;win++;} } for (int i=1;i<=n;i++) { if (ans[i]==0) { if (a>0) {ans[i]=‘R‘;a--;continue;} if (b>0) {ans[i]=‘P‘;b--;continue;} if (c>0) {ans[i]=‘S‘;c--;continue;} } } if ((n%2==1&&win>=(n+1)/2)||(n%2==0&&win>=n/2)) { printf("YES "); for (int i=1;i<=n;i++) printf("%c",ans[i]); printf(" "); } else { printf("NO "); } } }
以上是关于2019.11.16工作坊比赛题解的主要内容,如果未能解决你的问题,请参考以下文章
两个乒乓球队进行比赛,各出三人。甲队为a,b,c三人,乙队为x,y,z三人。 已抽签决定比赛名单。有人向队员打听比赛的名单。 a说他不和x比,c说他不和x,z比,请编程序找出三队赛手的名单。(代码片段