补题2.9

糖果

思路:

通过观察发现,糖果的种类数量少,并且对n包糖果如果进行直接组合处理的话那么就是2^100会超时,则可以考虑用状压来表示每一种的糖果,那么定义dp状态表示为:

dp[i]表示,糖果种类组合为i所需的最少糖果包数,那么转移方程为在考虑i时,加入某一包糖果j,那么就直接取min即可,

#include<bits/stdc++.h>
using namespace std;
#define ll long long 
const int inf=0x3f3f3f3f;
const int N=2e5+5;
int dp[1<<20],w[105];
int main(){
    int n,m,k;
    cin>>n>>m>>k;
    memset(dp,inf,sizeof(dp));
    for(int i=0;i<n;i++){
        int t=0;
        for(int j=0;j<k;j++){
            int a;
            cin>>a;
            t|=(1<<(a-1));
        }w[i]=t;
        dp[t]=1;
    }for(int i=0;i<(1<<m);i++){
        if(dp[i]!=inf){
            for(int j=0;j<n;j++){
                int t=w[j];
                dp[i|t]=min(dp[i]+1,dp[i|t]);
            }
        }
    }cout<<dp[(1<<m)-1];
    return 0;
}

A. Reverse and Concatenate

思路:

如果初始的字符串就是回文串,那么能够生成的种类就为1,

否则,特判一下k==0的情况,其它的就是2.

#include<bits/stdc++.h>
using namespace std;
#define ll long long 
const int N=2e5+5;
const int inf=0x3f3f3f3f;
void solve(){
    int n,k;
    cin>>n>>k;
    string s;
    cin>>s;
    int f=1;
    for(int i=0;i<n;i++){
        if(s[i]!=s[n-i-1]){
            f=0;break;
        }
    }if(f){
        cout<<"1\n";
    }else{
        if(k==0)cout<<"1\n";
        else cout<<"2\n";
    }
}
int main(){
    int t=1;
    cin>>t;
    while(t--){
        solve();
    }
    return 0;
}

B. Fortune Telling

思路:

题目只需要判断谁能赢就可,不必考虑如何赢的情况,并且保证有且只有一人获胜的情况。

那么我们只需要特判赢的情况即可,考虑题目中的两种操作,异或、+,其操作之后数的奇偶性是一定的,那么我们只需要看最后的y是奇偶,和操作之后能得到的是否是对应的奇偶即可。

#include<bits/stdc++.h>
using namespace std;
#define ll long long 
const int N=2e5+5;
const int inf=0x3f3f3f3f;
void solve(){
   ll n,x,y;
   cin>>n>>x>>y;
   int cnt=0;
   if(x&1)cnt++;
   for(int i=1;i<=n;i++){
       int a;
       cin>>a;
       if(a&1)cnt++;
   }if(cnt%2==y%2){
       cout<<"Alice\n";
   }else cout<<"Bob\n";
}
int main(){
    int t=1;
    cin>>t;
    while(t--){
        solve();
    }
    return 0;
}

C. OKEA

思路:

要保证平均数为整数,那么最优的情况就是公差为2的等差数列,那么相当于是将长度为2*m的数进行奇偶分开,依次填充即可,考虑到要[1,n*m]都使用到且只使用一次,那么n就只能是偶数,特判当m==1的时候,不必考虑n的奇偶性。

#include<bits/stdc++.h>
using namespace std;
#define ll long long 
const int N=2e5+5;
int ans[505][505];
void solve(){
    int n,m;
    cin>>n>>m;
    if(m==1){
        cout<<"YES\n";
        for(int i=1;i<=n;i++)cout<<i<<"\n";
        return ;
    }if(n&1){
        cout<<"NO\n";
        return ;
    }cout<<"YES\n";
	for(int i=1;i<=n;i+=2){
        int pos=(i-1)*m+1;
        for(int j=1;j<=m;j++){
            cout<<pos<<" ";
            pos+=2;
        }pos=(i-1)*m+2;
        cout<<"\n";
        for(int j=1;j<=m;j++){
            cout<<pos<<" ";
            pos+=2;
        }cout<<"\n";
    }
    
}
int main(){
    int t=1;
    cin>>t;
    while(t--){
        solve();
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值