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

原创 2015年11月17日 17:36:10

这里写图片描述
现场赛教练嫌弃我们渣,没让我们去,没办法,小菜只能赛后开了场,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;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

2016中国大学生程序设计竞赛(ccpc 长春)题解报告

2016中国大学生程序设计竞赛(ccpc 长春)题解报告

CCPC - k题(dp)

本题目的意思: 给定n个位置,每个位置有一个二元组,要求确定n个位置的属性(选1或者是2),使得每个二元组的1属性和2属性去最近的位置,总代价最小(代价 属性值*移动距离) 分析: 可以尝试如此规划,...

2015南阳CCPC部分题目代码

我是部分按照难度来排序的,越简单的越前面。 首先是L题。 #include #include using namespace std; int main() { int t;scanf("...

2015年ccpc赛后总结:

2015年ccpc赛后总结:        讲起赛后总结,我想先说一下,赛前的个人感受.这次南阳的比赛,是我和我的队友争取到的一次宝贵的机会,当然要感谢老师,感谢....太多了,他们给我们创造了这个...

2015 CCPC 这次,我为自己鼓掌

这一次,我为自己鼓掌     当听说ccpc在我们学校举办的时候,很惊讶,也很激动,同时也心里也是比较遗憾的,这次比赛与我无缘,我只能做一个观众,默默的看着曾经的队友、朋友功成名就,自己继续一个人待在...

CCPC 2017 哈尔滨赛区现场赛 比赛总结

非常感谢老师给我们队的这个机会,让我们去参加这场比赛。两个队友以前都是参加过省赛,但是我这次是第一次参加现场赛,难免有点紧张。请假以及坐车到哈尔滨一路都还比较顺利,到那里之后晚上在哈商大宾馆住,环境还...

C++面试查找字符串中是否包含另一个字符串

从字符串str1中查找是否有符串str2,如果有返回true 如果没有,返回false

杭电OJ——1124 Factorial(水题)

Factorial Problem Description The most important part of a GSM network is so called Base Tra...

【HDU5550 2015 CCPC 南阳国赛K】【DP 脑洞 好题】 Game Rooms 每层楼一属性,所有人各得其所 数轴映射+同属性区间段整体更新

#include #include #include #include #include #include #include #include #include #include #include #...

牛客网--前端面试经典题目合集总结(持续更新)

前端面试经典题目总结
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:2015CCPC题目总结(小菜持续更新)
举报原因:
原因补充:

(最多只允许输入30个字)