【codeforces】Round #522 (Div. 2) A+B+C+D

目录


 【A. Kitchen Utensils】

题目链接:https://codeforces.com/contest/1079/problem/A

【题意】国王的大聚餐,但是会有人偷东西。每一道菜需要一套餐具,每个人有若干道菜。此时,宴会厅里还剩下n个餐具,已知有k个人来用餐。然后n个整数标记不同的餐具,值相同的代表同一个餐具。求被偷餐具的最小值。

【分析】思维,想清楚就行了

【代码】

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
using namespace std;

const int maxn=105;
int num[maxn];

int main()
{
	int n,k,cnt=0;
	memset(num,0,sizeof(num));
	scanf("%d%d",&n,&k);
	for(int i=0;i<n;i++)
	{
		int x;scanf("%d",&x);
		if(!num[x])cnt++;
		num[x]++;
	}
	int maxx=-1;
	for(int i=0;i<105;i++)
		maxx=max(maxx,num[i]);
	int ans=(maxx%k!=0)+maxx/k;
	ans=ans*k*cnt-n;
	if(cnt==1 && n%k)ans=k-n%k;
	cout<<ans<<endl;
	return 0;
}

【B. Personalized Cup】

题目链接:https://codeforces.com/contest/1079/problem/B

【题目】给你一个字符串,长度不超过100,要求输出最小的行数和列数是的每行字符数≤20并且行数≤5,不能整除的可用'*'补齐,并且任意两行'*'的个数差值最多为1,多个符合条件的任意输出一组即可。

【分析】行数从1到5开始寻找满足条件的,然后求'*'的数目,再输出即可;

【代码】

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<string>
using namespace std;

const int maxn=105;
char s[maxn];

int main()
{
	scanf("%s",s);
	int len=strlen(s);
	int row=1,col=len;
	for(int i=1;i<=5;i++)
	{
		row=i;
		col=min(col,len/row+((len%row==0)?0:1) );
		if(col<=20)break;
	}
	printf("%d %d\n",row,col);
	int star=row*col-len;
	int x,y,now=0,j=0;
	for(int i=0;i<len;i++)
	{
		if(star>0 && j==0)printf("*"),j++,star--;
		printf("%c",s[i]),j++;
		if(j==col)puts(""),j=0;
	}
	return 0;	
}

【C. Playing Piano】

题目链接:https://codeforces.com/contest/1079/problem/C

【题意】给你乐谱,每个对应位置,越大越靠右,然后用一只手去弹,且满足:

  • if a[i]<a[i+1] then b[i]<b[i+1]
  • if a[i]>a[i+1] then b[i]>b[i+1]
  • if a[i]=a[i+1] then b[i]≠b[i+1]

【分析】做法挺多的吧 

1. 贪心

  • 贪心考虑当前位置以及之后的两个位置,是放1还是5还是3还是相邻数
  • 注意continue是停止执行循环语句不是if语句!!卡了半天难过(ಥ﹏ಥ)

【代码】

#include<bits/stdc++.h>
using namespace std;

const int maxn=1e5+5;
int a[maxn],now;
vector<int>ans;

int main()
{
	int n;scanf("%d",&n);
	for(int i=0;i<n;i++)scanf("%d",&a[i]);
	if(a[0]==a[1])ans.push_back(3);
	else if(a[0]<a[1])ans.push_back(1);
	else ans.push_back(5);
	for(int i=0;i<n-1;i++)
	{
		if(a[i]<a[i+1] && ans[i]==5)
		{
			puts("-1");return 0;
		}
		if(a[i]>a[i+1] && ans[i]==1)
		{
			puts("-1");return 0;
		}
  		if(a[i+1]>a[i]) now=(a[i+2]<a[i+1]&&i<n-2?5:ans[i]+1);
		else if(a[i+1]<a[i]) now=(a[i+2]>a[i+1]&&i<n-2?1:ans[i]-1);
		else
		{
			now=(ans[i]==3?2:3);
			if(i<n-2)
			{
				if(a[i+1]<a[i+2]) now=(ans[i]==1?2:1);
				else if(a[i+1]>a[i+2]) now=(ans[i]==5?4:5);	
			}	
		}
		ans.push_back(now);
	}
	for(int i=0;i<ans.size();i++)
		printf("%d ",ans[i]);
	return 0;
}

2. dp

  •  dp[i][j] 表示要生成的序列的第i个位置值为j是否可行(0/1)
  • pre[i][j] 表示当前状态的前一个状态

【代码】

#include<bits/stdc++.h>
using namespace std;

const int maxn=1e5+5;
int n,a[maxn];
int dp[maxn][6];
int ans[maxn],pre[maxn][6];

int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)scanf("%d",&a[i]);
    for(int i=1;i<=5;i++)dp[1][i]=1;
    for(int i=1;i<n;i++)
    {
    	for(int j=1;j<=5;j++)
    	{
    		if(dp[i][j]==0)continue;
    		if(a[i]<a[i+1])
    		{
    			for(int k=j+1;k<=5;k++)
    			{
    				dp[i+1][k]=1;
    				pre[i+1][k]=j;
				}
			}
			else if(a[i]>a[i+1])
			{
				for(int k=1;k<j;k++)
				{
					dp[i+1][k]=1;
					pre[i+1][k]=j;
				}
			}
			else
			{
				for(int k=1;k<=5;k++)
				{
					if(k==j)continue;
					dp[i+1][k]=1;
					pre[i+1][k]=j;
				}
			}
		}
	}
    int flag=0,now;
    for(int i=1;i<=5;i++)
    {
    	if(dp[n][i])
    	{
    		now=i;
    		for(int j=n;j>=1;j--)
    		{
    			ans[j]=now;
    			now=pre[j][now];
			}
			flag=1;break;
		}
	}
    if(!flag) puts("-1");
    else
        for(int i=1;i<=n;i++)
            (i==1)?printf("%d",ans[i]):printf(" %d",ans[i]);
    return 0;
}

【D. Barcelonian Distance】

题目链接:https://codeforces.com/contest/1079/problem/D

【题意】求点A到点B的最短距离,走网格线或者走给出的直线。注意考虑直线与坐标轴平行的两种情况。然后就,路径就5种情况,枚举就好了。

【代码】

#include<bits/stdc++.h>
using namespace std;

double getDis(double x1,double y1,double x2,double y2)
{
	return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
}

int main()
{
	double a,b,c; scanf("%lf%lf%lf",&a,&b,&c);
	double x1,y1,x2,y2;
	double x11,y11,x22,y22;
	double x0,y0;
	scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
	double dis=0,dis1,dis2,dis3,dis4,Dis1,Dis2,Dis3,Dis4,Dis5;
	if(x1==x2)dis=fabs(y1-y2);
	else if(y1==y2)dis=fabs(x1-x2);
	else
	{
		if(a==0 || b==0) dis=fabs(x1-x2)+fabs(y1-y2);
		else
		{
			x11=-(c+b*y1)/a;y11=-(c+a*x1)/b;
			x22=-(c+b*y2)/a;y22=-(c+a*x2)/b;
			dis1=fabs(x1-x11),dis2=fabs(y1-y11),dis3=fabs(y2-y22),dis4=fabs(x22-x2);
			Dis1=dis1+dis3+getDis(x11,y1,x2,y22);
			Dis2=dis1+dis4+getDis(x11,y1,x22,y2);
			Dis3=dis2+dis3+getDis(x1,y11,x2,y22);
			Dis4=dis2+dis4+getDis(x1,y11,x22,y2);
			Dis5=abs(x1-x2)+abs(y1-y2);
			dis=min(Dis1,min(Dis2,min(Dis3,min(Dis4,Dis5))));
		}
	}
	 printf("%.10lf\n",dis);
}
 
 
 

猜你喜欢

转载自blog.csdn.net/qq_38735931/article/details/84572529