CSL分苹果 小埋与扫雷 Doors Breaking and Repairing Key Set Balanced Ternary String

第一题CSL分苹果

思路:基础动态规划,设m为所有苹果的数量和,dp[x]为,容量为x时候能分的最多苹果数目,那么wavator分到的最多苹果数目就是dp[m/2],tokitsukaze分到的苹果数目就是m-dp[m/2],
下面上代码。

#include<bits/stdc++.h>
#define GET_POS(c,x) (lower_bound(c.begin(),c.end(),x)-c.begin())
#define CASET int ___T; scanf("%d", &___T); for(int cs=1;cs<=___T;cs++)
#define MP make_pair
#define PB push_back
#define MS0(X) memset((X), 0, sizeof((X)))
#define MS1(X) memset((X), -1, sizeof((X)))
#define LEN(X) strlen(X)
#define F first
#define S second
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
typedef long double LD;
const int mod = 1e8 + 7;
const int MAXN = 1e6 + 10;
const int INF = 0x3f3f3f3f;
int dp[MAXN],a[MAXN],m,n;
int main()
{
    ios::sync_with_stdio(false);
    cin>>n;
    for(int i=1;i<=n;i++)
        cin>>a[i],m+=a[i];
    for(int i=1;i<=n;i++)
    for(int j=m;j>=a[i];j--)
    dp[j]=max(dp[j],dp[j-a[i]]+a[i]);
    cout<<dp[m/2]<<" "<<m-dp[m/2]<<endl;
}

小埋与扫雷

思路:读懂题很重要,3bv= 周围八格没有“空格”的“数字”个数+“空"的个数。
先求周围八格没有“空格”的“数字”个数++“空"的个数。再求空的个数,这里为了方便计算,把有雷的格子标记为-1,无雷的格子标记为0,算出每个不是雷的格子的旁边八个格子有几个雷,当做这个格子的值,之后遍历每个“空格“,对每个数字进行判断,判断周围八个是否是空格。之后再dfs遍历出连通块的个数。
代码如下:

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e3+10;
int a[maxn][maxn],m,n;
bool vis[maxn][maxn];
int bv3;
int dix[8]={-1,-1,-1,0,0,1,1,1};
int diy[8]={-1,0,1,-1,1,-1,0,1};
void dfs(int x,int y)
{
    for(int i=0;i<8;i++)
    {
        int xx=x+dix[i],yy=y+diy[i];
        if(xx>=0&&xx<n&&yy>=0&&yy<m&&a[xx][yy]==0&&!vis[xx][yy])
        {
            vis[xx][yy]=true;
            dfs(xx,yy);
        }
    }
}
void sum(int x,int y)
{
    for(int  i=0;i<8;i++)
    {

        int dx=x+dix[i];
        int dy=y+diy[i];
        if(dx>=0&&dx<n&&dy>=0&&dy<m&&a[dx][dy]!=-1)
            a[dx][dy]++;
    }

}
int check(int x,int y)
{
    for(int i=0;i<8;i++)
    {
        int xx=x+dix[i];
        int yy=y+diy[i];
        if(xx>=0&&xx<n&&yy>=0&&yy<m&&a[xx][yy]==0)
        return 0;
    }
    return 1;
}
int main()
{

    cin>>n>>m;
    for(int i=0;i<n;i++)
    for(int j=0;j<m;j++)
    {

        cin>>a[i][j];
        if(a[i][j])a[i][j]=-1;
    }
    for(int i=0;i<n;i++)
    for(int j=0;j<m;j++)
    {
        if(a[i][j]==-1)sum(i,j);

    }
    for(int  i=0;i<n;i++)
    for(int  j=0;j<m;j++)
    {
        if(a[i][j]!=0&&a[i][j]!=-1&&check(i,j))bv3++;

    }
    int it=0;
    for(int i=0;i<n;i++)
        for(int j=0;j<m;j++)
    {
         if(a[i][j]==0&&!vis[i][j])
            {
                it++;
                dfs(i,j);
            }
    }
    cout<<bv3+it<<endl;
}


C. Doors Breaking and Repairing

题意:n个门,每个门有个坚固值,一个警察能拿个石头撞门每次撞X点伤害,小偷能不停的加固门,每次加固Y,问警察最多撞开几个门。

思路:题意大概是两个人玩游戏一个警察,一个坏蛋,一个人破门,一个人补门,警察像破开尽可能多的门,坏蛋想让警察破开门尽可能少,这时候就疑惑了,这到底是让我们求最大值,还是最小值?在这里我们看到,两个人的意愿也改变不了必然的结果,就拿这一组数据
6 3 2
2 3 1 3 4 2
6扇门,警察破门掉 3个耐久,坏蛋修门增加2个耐久,警察与坏蛋轮流操作,警察为破开更多的们,会选择第一次就能破开,或者说最小耐久值的门,坏蛋也是这样想的,他会修补那些一次就被警察破门的门,前提是坏蛋增加耐久大于警察破门,不然以题目这样的数据,一直撞迟早也是撞开的,当坏蛋修补增加的耐久大于警察撞门耐久时,便有了以下操作
5 5 6
1 2 6 10 3
警察第一次撞门 1
坏蛋第一次修门 2
警察第二次撞门 3
再往后警察一次撞不开一扇门,而坏蛋使门的耐久度越来越高,这就得出了必然的结果。

AC代码

#include<bits/stdc++.h>
#define GET_POS(c,x) (lower_bound(c.begin(),c.end(),x)-c.begin())
#define CASET int ___T; scanf("%d", &___T); for(int cs=1;cs<=___T;cs++)
#define MP make_pair
#define PB push_back
#define MS0(X) memset((X), 0, sizeof((X)))
#define MS1(X) memset((X), -1, sizeof((X)))
#define LEN(X) strlen(X)
#define F first
#define S second
using namespace std;
typedef long long ll;
typedef unsigned long long ULL;
typedef long double LD;
const int mod = 1e8 + 7;
const int MAXN = 1e6 + 10;
const int INF = 0x3f3f3f3f;
int a[MAXN],n,x,y,ans;
int main()
{
    cin>>n>>x>>y;
    for(int i=1;i<=n;i++)
    {
        cin>>a[i];
        if(a[i]<=x)ans++;
    }
    if(x>y)cout<<n<<endl;
    else {
        if(ans&1)cout<<ans/2+1<<endl;
        else cout<<ans/2<<endl;
    }
}

Key Set

思路:多写两组数据就能看出来公式就是sum=2^(n-1)-1,直接快速幂不解释

AC代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ULL;
typedef long double LD;
const int mod = 1000000007;
const int MAXN = 1e6 + 10;
const int INF = 0x3f3f3f3f;
ll qpow(ll a,ll b)
{
    ll res=1;
    while(b)
    {
        if(b&1)res=(res*a)%mod;
        b=b/2;
        a=a*a%mod;
    }
    res=res%mod;
    return res;
}
int main()
{

    int t;
    cin>>t;
    while(t--)
    {
        int n;
        cin>>n;
        cout<<qpow(2,n-1)-1<<endl;
    }
}

D. Balanced Ternary String

题意:一串只包含012且长度为n的字符串,然后让你替换字符,使得在替换的次数最少的前提下,使得新获得的字符串中0,1,2这三个字 符的数目相同,并且新获得的字符串字典序要尽可能的小。

思路:首先考虑贪心,三种情况
0多的时候,从后往前遍历,依次补2,补1
1多的时候,补2的时候从后往前遍历,补0的时候从前往后遍历
2多的时候,从前往后遍历,依次补0,补1。
另外在cf使用io流输入时候好像不能使用这一句。开始一直WA,后来把这句话去掉就A了,具体原因不清楚

ios::sync_with_stdio(false);

AC代码

#include<bits/stdc++.h>
using namespace std;
const int MAXN = 1e6 + 10;
const int INF = 0x3f3f3f3f;
char str[MAXN];
int mmp[4];
int main()
{
   
    int n;
    cin>>n;
    scanf("%s",str);
    for(int i=0;i<n;i++)
        mmp[str[i]-'0']++;
    int now=n/3;
 
    if(mmp[0]>now)
    {
 
        for(int i=n-1;i>=0;i--)
        {
            if(str[i]=='0')
            {
                if(mmp[2]<now&&mmp[0]>now)
                {
                    str[i]='2';
                    mmp[2]++;
                    mmp[0]--;
                }
                else if(mmp[1]<now&&mmp[0]>now)
                {
                    str[i]='1';
                    mmp[1]++;
                    mmp[0]--;
                }
            }
        }
    }
    if(mmp[1]>now)
    {
 
        for(int i=0;i<n;i++)
        {
            if(str[i]=='1')
            {
                if(mmp[0]<now&&mmp[1]>now)
                {
                    str[i]='0';
                    mmp[0]++;
                    mmp[1]--;
                }
            }
        }
        for(int i=n-1;i>=0;i--)
        {
            if(str[i]=='1')
            {
                if(mmp[2]<now&&mmp[1]>now)
                {
                    str[i]='2';
                    mmp[2]++;
                    mmp[1]--;
                }
            }
        }
    }
    if(mmp[2]>now)
    {
        for(int i=0;i<n;i++)
        {
            if(str[i]=='2')
            {
                if(mmp[0]<now&&mmp[2]>now)
                {
                    str[i]='0';
                    mmp[0]++;
                    mmp[2]--;
                }
                else if(mmp[1]<now&&mmp[2]>now)
                {
                    str[i]='1';
                    mmp[1]++;
                    mmp[2]--;
                }
            }
        }
 
    }
    printf("%s\n",str);
 
}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
Zotero CSL(Citation Style Language)是一个开源的、零配置的引用风格样式表语言。它是用于Zotero等引文管理软件的引文风格的标准化语言。Zotero是一个免费的引文管理工具,旨在帮助学者和研究人员轻松管理他们的研究文献和引文。 使用Zotero CSL,用户可以方便地根据特定的学术引文要求创建和编辑引文风格。这些风格可以包括学术期刊的引文要求、出版商的指导方针和特定领域的引文规范等。用户可以选择已经存在的引文风格,也可以根据需要自定义新的引文风格。 Zotero CSL借助于XML语言来描述引文风格。用户可以使用XML编写具体的引文格式,包括作者、标题、出版日期等等。另外,用户还可以通过使用条件语句、循环语句等来实现更复杂的引文格式要求。这些XML文件可以与Zotero和其他引文管理软件一起使用,以确保生成符合学术期刊或指导方针要求的引文。 除了提供标准的引文风格,Zotero CSL还具有自动更新的功能。一旦某个学术期刊或指导方针发布了新的引文要求,用户可以更新相应的CSL文件,以适应最新的引文规范。这样,用户就无需手动更改每个引文的格式,而是可以通过简单的更新方法自动应用新的引文风格。 总而言之,Zotero CSL提供了一个简单、强大和灵活的引文风格管理工具,可以帮助用户轻松地满足不同学术期刊或指导方针对引文格式的要求。同时,它还具有自动更新的特性,以确保用户始终使用最新的引文规范。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值