2015CCPC题目总结(小菜持续更新)

这里写图片描述
现场赛教练嫌弃我们渣,没让我们去,没办法,小菜只能赛后开了场,DP略虚,也只能拿个铜。
hdu5540
给你两个2X2矩阵,可以旋转,判断是否相等,水之


#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <set>
#include <queue>
#include <map>
#include <cmath>
#include <vector>
using namespace std;
#define N 500010
#define pi acos(-1.0)
#define inf 100000000
typedef long long ll;
typedef unsigned long long ull;
int a[2][2],b[2][2];
bool j(){
    for(int i=0;i<2;i++){
        for(int j=0;j<2;j++){
            if(a[i][j]!=b[i][j]) return false;
        }
    }
    return true;
}

void zhuan(){
    int tmp=a[0][0];
    a[0][0]=a[1][0];
    a[1][0]=a[1][1];
    a[1][1]=a[0][1];
    a[0][1]=tmp;
}
int main(){
    int t,cnt=0;
    scanf("%d",&t);
    while(t--){
        for(int i=0;i<2;i++){
            for(int j=0;j<2;j++){
                scanf("%d",&a[i][j]);
            }
        }
        for(int i=0;i<2;i++){
            for(int j=0;j<2;j++){
                scanf("%d",&b[i][j]);
            }
        }
        bool f=false;
        for(int i=0;i<4;i++){
            if(j()) f=true;
            zhuan();
        }
        if(f) printf("Case #%d: POSSIBLE\n",++cnt);
        else printf("Case #%d: IMPOSSIBLE\n",++cnt);
    }
    return 0;
}

hdu5542
DP果然很虚,看了别人的博客才明白
给你一个序列,在不改变序列原有顺序的前提下,求出上升子序列长度大于M的种类数
在这里dp[i][k]表示以第i个数字结尾的序列中,长度为k的种类数,那么很容易推出。
这里写图片描述
然后自然而然很容易写出

#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <set>
#include <queue>
#include <map>
#include <cmath>
#include <vector>
using namespace std;
#define N 1010
#define pi acos(-1.0)
#define inf 100000000
typedef long long ll;
typedef unsigned long long ull;
int a[N],dp[N][N];
int lowbit(int x){
    return x&(-x);
}
int main(){
    int t,n,m;
    scanf("%d",&t);
    int c=0;
    while(t--){
        scanf("%d%d",&n,&m);
        memset(dp,0,sizeof(dp));
        for(int i=1;i<=n;i++) scanf("%d",&a[i]);
        for(int i=1;i<=n;i++){
            dp[i][1]=1;
        }
        for(int i=1;i<=n;i++){
            for(int k=2;k<=m;k++){
                int sum=0;
                for(int j=1;j<i;j++){
                    if(a[j]<a[i]){
                        sum+=dp[j][k-1];
                    }
                }
                dp[i][k]=sum;
            }
        }
        int ans=0;
        for(int i=1;i<=n;i++){
            ans+=dp[i][m];
        }
        printf("Case #%d: %d\n",++c,ans);
    }   
    return 0;
}

然而,T你没商量
这肯定是要优化的,听说树状数组可以优化,所以学了发树状数组,现学现卖

#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <set>
#include <queue>
#include <map>
#include <cmath>
#include <vector>
using namespace std;
#define N 1010
#define pi acos(-1.0)
#define mod 1000000007
#define inf 100000000
typedef long long ll;
typedef unsigned long long ull;
int a[N],b[N];
int d[N][N];
int lowbit(int x){
    return x&(-x);
}

void update(int l,int x,int num)
{
    while(x<=N)
     {
         d[l][x]+=num;
         d[l][x]%=mod;
         x+=lowbit(x);
     }
}

int getSum(int l,int x)
{
    int s=0;
    while(x>0)
     {
         s+=d[l][x];
         s%=mod;
         x-=lowbit(x);
     }
    return s;
}

int main(){
    int t,n,m;
    scanf("%d",&t);
    int c=0;
    while(t--){
        scanf("%d%d",&n,&m);
        memset(d,0,sizeof(d));
        for(int i=1;i<=n;i++){
            scanf("%d",&a[i]);
            b[i]=a[i];
        }
        sort(b+1,b+1+n);
        for(int i=1;i<=n;i++) a[i]=lower_bound(b+1,b+n+1,a[i])-b;
        for(int i=1;i<=n;i++){
            for(int k=1;k<=m;k++){
                if(k==1) update(1,a[i],1);
                else{
                    int sum=getSum(k-1,a[i]-1);
                    update(k,a[i],sum);
                }
            }
        }
        int ans=getSum(m,n);
        printf("Case #%d: %d\n",++c,ans);
    }   
    return 0;
}

hdu5543
题意当时看到我就懵逼了,以为有一些木棍可以放在外边,所以就慌了,然而现在想了想,其实无非就是个背包。由于木棍可以放一半在外面,所以根据谈心策略,就放一半,由于奇数会产生浮点问题,所以这道题先都X2。
其实题意为,容器长度为L,每个物品有长度价值,然后有两次可以将物品折半放入的机会。
这不就是水背包呀。

#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <set>
#include <queue>
#include <map>
#include <cmath>
#include <vector>
using namespace std;
#define N 500010
#define pi acos(-1.0)
#define inf 100000000
typedef __int64 ll;
typedef unsigned long long ull;
ll a[1010],b[1010];
ll dp[4010][3];
int main(){
    int t,n,l;
    ll ans;
    scanf("%d",&t);
    int cnt=0;
    while(t--){
        memset(dp,0,sizeof(dp));
        scanf("%d%d",&n,&l);
        l*=2;
        ans=0;
        for(int i=1;i<=n;i++){
            scanf("%I64d%I64d",&a[i],&b[i]);
            a[i]<<=1;
            ans=max(ans,b[i]);
        }
        for(int i=1;i<=n;i++){
            for(int j=l;j>=a[i]/2;j--){
                for(int k=0;k<3;k++){
                    if(j>=a[i]) dp[j][k]=max(dp[j][k],dp[j-a[i]][k]+b[i]);
                    if(k>0) dp[j][k]=max(dp[j][k],dp[j-a[i]/2][k-1]+b[i]);
                }
            }
        }
        ans=max(ans,dp[l][2]);
        printf("Case #%d: %I64d\n",++cnt,ans);
    }
    return 0;
}

hdu5546
水题,只是我写搓了,差评

#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <set>
#include <queue>
#include <map>
#include <cmath>
#include <vector>
using namespace std;
#define N 500010
#define pi acos(-1.0)
#define inf 100000000
typedef long long ll;
typedef unsigned long long ull;
char s[20][20];
char tmp[20][20];
int dx[]={0,0,1,-1};
int dy[]={-1,1,0,0};
int vis[20][20];
bool ff;
bool jj(int x,int y){
    if(x<0||y<0||x>8||y>8) return false;
    return true;
}

bool checko(int x,int y){
    int xx,yy;
    vis[x][y]=1;
    if(s[x][y]=='.') return true;
    for(int i=0;i<4;i++){
        xx=x+dx[i];
        yy=y+dy[i];
        if(jj(xx,yy)&&!vis[xx][yy]&&s[xx][yy]!='x'&&checko(xx,yy)) return true;
    }
    return false;
}

bool checkx(int x,int y){
    int xx,yy;
    vis[x][y]=1;
    if(s[x][y]=='.') return true;
    for(int i=0;i<4;i++){
        xx=x+dx[i];
        yy=y+dy[i];
        if(jj(xx,yy)&&!vis[xx][yy]&&s[xx][yy]!='o'&&checkx(xx,yy)) return true;
    }
    return false;
}
void clear(char c){
    for(int i=0;i<9;i++){
        for(int j=0;j<9;j++){
            if(vis[i][j]) s[i][j]='.';
        }
    }
}
bool checko2(int x,int y){
    int xx,yy;
    vis[x][y]=1;
    if(tmp[x][y]=='.') return true;
    for(int i=0;i<4;i++){
        xx=x+dx[i];
        yy=y+dy[i];
        if(jj(xx,yy)&&!vis[xx][yy]&&tmp[xx][yy]!='x'&&checko2(xx,yy)) return true;
    }
    return false;
}

void clear2(char c){
    for(int i=0;i<9;i++){
        for(int j=0;j<9;j++){
            if(vis[i][j]) tmp[i][j]='.';
        }
    }
}
void cc(){
    for(int i=0;i<9;i++){
        for(int j=0;j<9;j++){
            if(s[i][j]=='o'){
                memset(vis,0,sizeof(vis));
                if(!checko(i,j)) clear('o');
            }
        }
    }
    for(int i=0;i<9;i++){
        for(int j=0;j<9;j++){
            if(s[i][j]=='x'){
                memset(vis,0,sizeof(vis));
                if(!checkx(i,j)) clear('x');
            }
        }
    }
}
void cc2(){
    for(int i=0;i<9;i++){
        for(int j=0;j<9;j++){
            if(s[i][j]=='o'){
                memset(vis,0,sizeof(vis));
                if(!checko2(i,j)){
                    ff=true;
                    clear2('o');
                }
            }
        }
    }
}
void cop(){
    for(int i=0;i<9;i++)
      for(int j=0;j<9;j++)
        tmp[i][j]=s[i][j];
}
int main(){
    int t;
    scanf("%d",&t);
    int cnt=0;
    while(t--){
        for(int i=0;i<9;i++){
            scanf("%s",s[i]);
        }
        cc();
        ff=false;
        for(int i=0;i<9;i++){
            for(int j=0;j<9;j++){
                memset(vis,0,sizeof(vis));
                if(s[i][j]=='.'){
                    s[i][j]='x';
                    cop();
                    cc2();
                    s[i][j]='.';
                }
            }
        }
        if(ff) printf("Case #%d: Can kill in one move!!!\n",++cnt);
        else printf("Case #%d: Can not kill in one move!!!\n",++cnt);
    }
    return 0;
}

hdu 5547
水题

#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <set>
#include <queue>
#include <map>
#include <cmath>
#include <vector>
using namespace std;
#define N 500010
#define pi acos(-1.0)
#define inf 100000000
typedef long long ll;
typedef unsigned long long ull;
char s[10][10];
int a[4];

void gao(int x,int y){
    for(int i=0;i<4;i++){
        if(s[i][y]!='*') a[s[i][y]-'1']=1;
        if(s[x][i]!='*') a[s[x][i]-'1']=1;
    }
    x=x/2*2;
    y=y/2*2;
    for(int i=x;i<x+2;i++)
      for(int j=y;j<y+2;j++)
        if(s[i][j]!='*')
          a[s[i][j]-'1']=1;
}
int main(){
    int t,c=0;
    scanf("%d",&t);
    while(t--){
        printf("Case #%d:\n",++c);
        for(int i=0;i<4;i++) scanf("%s",s[i]);
        bool f=true;
        while(f){
            f=false;
            for(int i=0;i<4;i++)
              for(int j=0;j<4;j++)
                if(s[i][j]=='*'){
                    f=true;
                    memset(a,0,sizeof(a));
                    gao(i,j);
                    int cnt=0,k;
                    for(int p=0;p<4;p++){
                        if(!a[p]){
                            cnt++;
                            k=p+1;
                        }
                    }
                    if(cnt==1) s[i][j]='0'+k;
                }
        }
        for(int i=0;i<4;i++){
              for(int j=0;j<4;j++)
                cout<<s[i][j];
              cout<<endl;
        }
    }
    return 0;
}

hdu5551
水题

#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <set>
#include <queue>
#include <map>
#include <cmath>
#include <vector>
using namespace std;
#define N 500010
#define pi acos(-1.0)
#define inf 100000000
typedef long long ll;
typedef unsigned long long ull;
int main(){
    int t,n;
    scanf("%d",&t);
    int cnt=0;
    while(t--){
        scanf("%d",&n);
        printf("Case #%d: %d\n",++cnt,2*n-1);
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值