Codeforces Round #522 2019 ABC

A - Kitchen Utensils

#include<bits/stdc++.h>
using namespace std;
int a[110];
int main()
{
    int n,m;
    while(~scanf("%d %d",&n,&m))
    {   int x,c=0,maxv=-1;memset(a,0,sizeof a);
        for(int i=1;i<=n;i++){
            scanf("%d",&x);if(a[x]==0) c++;//种类数
            a[x]++;maxv=max(maxv,a[x]);//最大值
        }
        int v=maxv/m,ans=0;//至少有多少份
        if(maxv%m) v++;//v++
            ans=v*c*m-n;
        printf("%d\n",ans);
    }
}

B - Personalized Cup

给你一片文章,让你把每个字符放在一个ab的网格中,每一个位置可以是或者字符,要求为行数不超过5,列数不超过20,每相邻两行之间的*数量不能超过1.求满足条件的矩阵中行数最少的,行数相同取列最少的

#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;
const int   N= 1e5+5;
int n,sz,cnum,rnum,last;
string s;
bool p;
int main(){

    cin>>s;
    n= s.size();//printf("%d\n",n);
    cnum= (n/20)+(!!(n%20));//行
    rnum= (n/cnum)+(!!(n%cnum));//列
    cout<<cnum<<" "<<rnum<<'\n';

    for(int i=0;i<cnum;i++){
     if((n%cnum) && (n%cnum)==i){
           rnum--;//
          // printf("%d\n",rnum);
          p=1;
     }
      for(int j=last;j<last+rnum;j++)
         cout<<s[j];
       last+=rnum;
      if(p)
          cout<<'*';//补芯
      cout<<'\n';
    }

   return 0;

}

C - Playing Piano

贪心:

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5+7;
int a[maxn],b[maxn],n;
int main()
{
  scanf("%d",&n);
  a[n]=maxn;
  for(int i=0; i<n; i++)
    scanf("%d",&a[i]);
  b[0]= a[0]<a[1]?1:(a[0]==a[1]?3:5);///  贪心第一个为1,3,5
  for(int i=1; i<n; i++)
  {
    if(a[i]==a[i-1]) {
     
      if(a[i]==a[i+1]) //中间 取中间数
        b[i] = b[i-1]!=3?3:2;///上一个不是3那就贪3,否则4和2都可以
      else if(a[i]<a[i+1])
        b[i] = b[i-1]!=1?1:2;///明显是一个谷底,贪最小的
      else if(a[i]>a[i+1])///山头,贪最大
        b[i] = b[i-1]!=5?5:4;
    }
    else if(a[i]>a[i-1])
      b[i] = (a[i]>a[i+1]&&b[i-1]!=5)?5:b[i-1]+1;
///如果是山头并且没到顶(5),那就贪5,不然两种情况,
///一种是递增(a[i]<=a[i+1])的那就贪花费少,也就是+1
///另一种是山头到顶,一样+1变6被排除
    else
      b[i] = (a[i]<a[i+1]&&b[i-1]!=1)?1:b[i-1]-1;///同上,谷底
    if(b[i]<1||b[i]>5) ///超出范围
    {
      printf("-1\n");
      return 0;
    }
  }
  for(int i=0; i<n; i++)
    printf("%d ",b[i]);
  return 0;
}

dp:

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define mem(a,x) memset(a,x,sizeof(a))
#define se second
#define fi first
const ll mod=1e9+7;
const int INF= 0x3f3f3f3f;
const int N=1e5+5;

int n,a[N];
int dp[N][6];//第i个位置的值为k是否可行
int ans[N];
int pre[N][6];//记录每个第i个位置上可取的值

int main()
{
    cin>>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,k;j<=5;j++)//下一位 取值是否可行
        {
            if(dp[i][j]==0) continue;//状态不可行

            if( a[i] < a[i+1] )
            {
                for( k=j+1;k<=5;k++)//i+1 位的可取值
                {
                    dp[i+1][k]=1;
                    pre[i+1][k]=j;//记录i位的取值
                }
            }
            else if( a[i] > a[i+1] )
            {
                for(int k=1;k<=j-1;k++)
                {
                    dp[i+1][k]=1;
                    pre[i+1][k]=j;
                }
            }
            else
            {
                for(int k=1;k<=5;k++)
                {
                    if(j==k) continue;//不可以相同
                    dp[i+1][k]=1;
                    pre[i+1][k]=j;
                }
            }

        }
    }

    int flag=0;
    int u;
    for(int i=1;i<=5;i++)
    {
        if(dp[n][i])
        {
            u=i;
            for(int j=n;j>=1;j--)
            {
                ans[j]=u;//逆推 记录答案
                u=pre[j][u];
            }
            flag=1; break;
        }
    }
    if(!flag)
        cout<<-1<<endl;
    else
    {
        for(int i=1;i<=n;i++)
            cout<<ans[i]<<' ';
    }
}

猜你喜欢

转载自blog.csdn.net/qq_41668093/article/details/84444744
今日推荐