Codeforces Round #297 (Div. 2) 纪念第一次Div2 AK

// 虽然是virtual participant但还是爽到、

A Vitaliy and Pie

题目链接:点击打开链接

思路:水题

AC代码:

#include <iostream>
#include <iomanip>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <queue>

using namespace std;

#define FSIO  ios::sync_with_stdio(0);cin.tie(0);
#define DEBUG(a)   cout<<"DEBUG: "<<(a)<<endl;

const int MAXN = 100005;
const int MOD = 1e9+7;
const int INF = 1e9+7;

int cnt[50];

int main()
{
    FSIO;
    int N;
    string sst;
    while(cin>>N)
    {
        cin>>sst;
        memset(cnt,0,sizeof(cnt));
        int ans = 0;
        for(int i=0;i<sst.length();++i)
        {
            if(sst[i]>='a'&&sst[i]<='z')    cnt[sst[i]-'a']++;
            else
            {
                if(cnt[sst[i]-'A']==0)  ans++;
                else    cnt[sst[i]-'A']--;
            }
        }
        cout<<ans<<endl;
    }

    return 0;
}



B Pasha and String

题目链接:点击打开链接

题意:给以串和n次反转操作,每次反转 a_i 到 len-a_i+1,(关于中心对称)

思路:从第一个字母到中间字母,用前缀和记录翻转操作次数,偶数不反转,奇数反转。

AC代码:

#include <iostream>
#include <iomanip>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <queue>

using namespace std;

#define FSIO  ios::sync_with_stdio(0);cin.tie(0);
#define DEBUG(a)   cout<<"DEBUG: "<<(a)<<endl;

const int MAXN = 100005;
const int MOD = 1e9+7;
const int INF = 1e9+7;

string nnn;
int mk[MAXN];

int main()
{
    FSIO;
    int M;
    while(cin>>nnn)
    {
        cin>>M;
        memset(mk,0,sizeof(mk));
        int tmp;
        for(int i=1;i<=M;++i)
        {
            cin>>tmp;
            mk[tmp]++;
        }
        long long summ = 0;
        for(int i=0;i<nnn.length()/2;++i)
        {
            summ = summ + mk[i+1];
            mk[i+1] = summ%2;
            if(mk[i+1])   swap(nnn[i],nnn[nnn.length()-i-1]);
        }
        cout<<nnn<<endl;
    }

    return 0;
}


C Ilya and Cubes

题目链接:点击打开链接

题意:给你n根棍子,每根棍子长为a_i,每根棍子长度可以减1,使用四根如长为b, b, c, c的棍子可以拼成一个矩形。问这些棍子能拼成的最大举行面积之和。

思路:贪心。每根棍子只能和自己长度一样的或者少1长的棍子组合。故只需要排序,从大到小不断找这样组合累加就好了。

AC代码:

#include <iostream>
#include <iomanip>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <queue>

using namespace std;

#define FSIO  ios::sync_with_stdio(0);cin.tie(0);
#define DEBUG(a)   cout<<"DEBUG: "<<(a)<<endl;

const int MAXN = 100005;
const int MOD = 1e9+7;
const int INF = 1e9+7;

long long stick[MAXN];
long long curx, cury;


int main()
{
    FSIO;
    int N;
    while(cin>>N)
    {

        for(int i=1;i<=N;++i)   cin>>stick[i];
        long long ans = 0;
        curx = 0;
        sort(stick+1,stick+1+N);
        for(int i=N;i>=1;--i)
        {
            if(stick[i]==-1)    continue;
            if(i>=2)
            {
                if(stick[i]-stick[i-1]>1)   continue;
                if(curx!=0)
                {
                    ans = ans + curx*min(stick[i],stick[i-1]);
                    curx = 0;
                }
                else    curx = min(stick[i],stick[i-1]);
                stick[i-1] = -1;
            }
        }
        cout<<ans<<endl;
    }
    return 0;
}



D Arthur and Walls

题目链接:点击打开链接

题意:一个N x M的地方,*代表墙,相邻的 . 组合代表房间,现在要你敲掉最小的墙的数量将所有房间都变成矩形。问最后这块地方是怎样的。

思路:需要敲墙的时候,必然是对于四个邻接点有一个*,所以只需要不断地找这样的方格改变就好了。

AC代码:

#include <iostream>
#include <iomanip>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <queue>

using namespace std;

#define FSIO  ios::sync_with_stdio(0);cin.tie(0);
#define DEBUG(a)   cout<<"DEBUG: "<<(a)<<endl;

const int MAXN = 2005;
const int MOD = 1e9+7;
const int INF = 1e9+7;

char mapp[MAXN][MAXN];
int N, M;

void dfs(int x, int y)
{
    int cnt = 0;
    if(x+1>N||y+1>M||x<1||y<1)    return;
    int ggx, ggy;   ggx=ggy=-1;
    for(int i=x;i<=x+1;++i)
        for(int j=y;j<=y+1;++j)
            if(mapp[i][j]=='*')
            {
                ggx=i;
                ggy=j;
                cnt++;
            }
    if(cnt==1)
    {
        mapp[ggx][ggy] = '.';
        dfs(x-1,y);dfs(x-1,y-1);
        dfs(x,y-1);dfs(x-1,y+1);
        dfs(x+1,y);dfs(x+1,y-1);
        dfs(x,y+1);dfs(x+1,y+1);
    }
}

int main()
{
    FSIO;
    while(cin>>N>>M)
    {
        memset(mapp,0,sizeof(mapp));
        for(int i=1;i<=N;++i)
            for(int j=1;j<=M;++j)
                cin>>mapp[i][j];
        for(int i=1;i<N;++i)
            for(int j=1;j<M;++j)
                dfs(i,j);
        for(int i=1;i<=N;++i)
        {
            for(int j=1;j<=M;++j)
                cout<<mapp[i][j];
            cout<<endl;
        }
    }

    return 0;
}



E Anya and Cubes

题目链接:点击打开链接

题意:有n个立方体,上面标有数字num,你可以使用贴纸将其变为num!。现在给你n个立方体,k个贴纸,和一个数字S,要你求经过一系列操作之后选则一定数量的立方体求其上数字之和为S的方案数。

思路:首先,S范围不超过1e16,故只有原标数字小于19的立方体贴纸才有意义。而一个立方体只有三种可能,即不取,取原数字,取原数字的阶乘。

考虑到暴力枚举所有方案,很难存储下这么多数据。

故不妨将原盒子分为两部分来凑成S。这样复杂度变为O(12^3 * 13^3 * 25),而考虑到每次枚举完后,k不可能每次都那么大,故复杂度近似为O(1e9)。

AC代码如下:

#include <iostream>
#include <iomanip>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <queue>

using namespace std;

#define FSIO  ios::sync_with_stdio(0);cin.tie(0);
#define DEBUG(a)   cout<<"DEBUG: "<<(a)<<endl;

const int MAXN = 100005;
const int MOD = 1e9+7;
const int INF = 1e9+7;

long long fac[25];
map<long long, int> res[30];
long long num[30];
long long S;
int n, k, mid;
long long ans;

void init()
{
    fac[0] = 1;
    for(int i=1;i<19;++i)
        fac[i] = (long long)i*fac[i-1];
}

void foredfs(int index, int kki, long long summ)
{
    if(kki>k||summ>S)   return ;
    if(index>n)
    {
        res[kki][summ]++;
        return;
    }
    if(num[index]<19)  foredfs(index+1,kki+1,summ+fac[num[index]]);
    foredfs(index+1,kki,summ+num[index]);
    foredfs(index+1,kki,summ);
}

void aftdfs(int index, int kki, long long summ)
{
    if(kki>k||summ>S)   return ;
    if(index>mid)
    {
        for(int i=0;i<=k-kki;++i)
            ans = ans + res[i][S-summ];
        return;
    }
    if(num[index]<19)  aftdfs(index+1,kki+1,summ+fac[num[index]]);
    aftdfs(index+1,kki,summ+num[index]);
    aftdfs(index+1,kki,summ);
}

int main()
{
    init();
    while(scanf("%d%d%I64d",&n,&k,&S)!=EOF)
    {
        for(int i=1;i<=n;++i)   scanf("%I64d",num+i);
        ans = 0;
        for(int i=0;i<=k;++i)   res[i].clear();
        mid = n/2;
        foredfs(mid+1,0,0);
        aftdfs(1,0,0);

        printf("%I64d\n",ans);
    }

    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值