目錄
【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);
}