【NOIP2015 提高组 day1】

今天,超级小周迎来了他人生第9次考试【NOIP2015 提高组 day1】,热心的他为了题解快肝爆了......

【NOIP2015 提高组 day1】神奇的幻方

【NOIP2015 提高组 day1】信息传递

【NOIP2015 提高组 day1】斗地主

【NOIP2015 提高组 day1】神奇的幻方

超级小周的思路:简单模拟送分

#include<bits/stdc++.h>
using namespace std;
int N,a[40][40],K=2,x,y;
int main(){
    //freopen("magic.in","r",stdin);
    //freopen("magic.out","w",stdout);
    cin>>N;
    if(N==1){
    cout<<"1";
    return 0;
    }
    if(N==3){
        cout<<'8'<<' '<<'1'<<' '<<'6'<<endl;
        cout<<'3'<<' '<<'5'<<' '<<'7'<<endl;
        cout<<'4'<<' '<<'9'<<' '<<'2'<<endl;
        return 0;
    }
    x=1;
    y=N/2+1;
    a[x][y]=1;
    for(K;K<=N*N;K++){
        if(x==1&&y!=N){
            x=N;
            y++;
            a[x][y]=K;
            continue;
        }
        if(x!=1&&y==N){
            x--;
            y=1;
            a[x][y]=K;
            continue;
        }
        if(x==1&&y==N){
            x++;
            a[x][y]=K;
            continue;
        }
        if(x!=1||y!=N){
            if(a[x-1][y+1]==0){
                x--;
                y++;
                a[x][y]=K;
                continue;
            }
            else {
                x++;
                a[x][y]=K;
                continue;
            }
        }
    }
        for(int i=1;i<=N;i++){
        for(int j=1;j<=N;j++){
            if(j==N)cout<<a[i][j];
            else
            cout<<a[i][j]<<" ";
        }
        cout<<endl;}

}

下一道( •̀ ω •́ )y

【NOIP2015 提高组 day1】信息传递

超级小周的思路:图论没认真学,考试考图论绝对爆0...qwq

并查集+最小环,找共同祖先构成环。

#include<bits/stdc++.h>
using namespace std;
int m=9999999,n,family[200010]={0},w[200010];
int qwq[200010],we[200010];
int sf(int st,int qwqqwqqwq){
    we[st]=0;
    if(st==we[0]) return qwqqwqqwq;
    else return sf(qwq[st],qwqqwqqwq+1);
}
int main(){

    scanf("%d",&n);
    for(int z=1;z<=n;++z){
        scanf("%d",&qwq[z]);
        ++we[qwq[z]];
    }
    for(int z=1;z<=n;++z)
        if(!we[z])
            family[++family[0]]=z;
    we[0]=1;
    while(1){
        if(we[0]&1){
            w[0]=0;
            for(int z=1;z<=family[0];++z){
                --we[qwq[family[z]]];
                if(!we[qwq[family[z]]]){
                    we[0]=2;
                    w[++w[0]]=qwq[family[z]];
                }
            }
            if(!w[0]) break;
        }
        else{
            family[0]=0;
            for(int z=1;z<=w[0];++z){
                --we[qwq[w[z]]];
                if(!we[qwq[w[z]]]){
                    we[0]=1;
                    family[++family[0]]=qwq[w[z]];
                }
            }
            if(!family[0]) break;
        }
    }
    for(int z=1;z<=n;++z)
        if(we[z]){
            we[0]=z;
            m=min(m,sf(qwq[z],1));
        }
    printf("%d",m);
}

下一题:

【NOIP2015 提高组 day1】斗地主

   

超级小周的思路:今天要是你十七张牌能把我lbw秒了 我当场把这个电脑屏幕吃掉

简单?的模拟,要有耐心...还要知道什么类型的牌先出最好。

#include<bits/stdc++.h>
using namespace std;
int T,n,ans,sum[25];
void dfs(int x)
{
    if (x>=ans) return;
    //顺子
    int k=0;//单顺子
    for (int i=3;i<=14;i++)
    {
        if(sum[i]==0) k=0;
        else
        {
            k++;
            if(k>=5)
            {
                for(int j=i;j>=i-k+1;j--) sum[j]--;
                dfs(x+1);
                for(int j=i;j>=i-k+1;j--) sum[j]++;
            }
        }
    }
    k=0;//双顺子
    for(int i=3;i<=14;i++)
    {
        if(sum[i]<=1) k=0;
        else 
        {
            k++;
            if(k>=3)
            {
                for(int j=i;j>=i-k+1;j--) sum[j]-=2;
                dfs(x+1);
                for(int j=i;j>=i-k+1;j--) sum[j]+=2;
            }
        }
    }
    k=0;//三顺子
    for(int i=3;i<=14;i++)
    {
        if(sum[i]<=2) k=0;
        else 
        {
            k++;
            if(k>=2)
            {
                for(int j=i;j>=i-k+1;j--) sum[j]-=3;
                dfs(x+1);
                for(int j=i;j>=i-k+1;j--) sum[j]+=3;
            }
        }
    }
    //带牌
    for(int i=2;i<=14;i++)//有3张或4张的牌
    {
        if(sum[i]<=3)
        {
            if(sum[i]<=2) continue;
            sum[i]-=3;
            for(int j=2;j<=15;j++)//带单张 
            {
                if(sum[j]<=0||j==i) continue;
                sum[j]--;
                dfs(x+1);
                sum[j]++;
            }
            for(int j=2;j<=14;j++)//带一对
            {
                if(sum[j]<=1||j==i) continue;
                sum[j]-=2;
                dfs(x+1);
                sum[j]+=2;
            }
            sum[i]+=3;
        } 
        else
        {
            sum[i]-=3;//3张带别的
            for(int j=2;j<=15;j++) //带单张  //以下原理同上
            {
                if(sum[j]<=0||j==i) continue;
                sum[j]--;
                dfs(x+1);
                sum[j]++;
            }
            for(int j=2;j<=14;j++) //带一对
            {
                if(sum[j]<=1||j==i) continue;
                sum[j]-=2;
                dfs(x+1);
                sum[j]+=2;
            }
            sum[i]+=3;

            sum[i]-=4; //4张带别的 
            for(int j=2;j<=15;j++) //带2个单张
            {
                if(sum[j]<=0||j==i) continue;
                sum[j]--;
                for (int k=2;k<=15;k++)
                {
                    if(sum[k]<=0||j==k) continue;
                    sum[k]--;
                    dfs(x+1);
                    sum[k]++;
                }
                sum[j]++;
            }
            for(int j=2;j<=14;j++)//带2个对儿
            {
                if(sum[j]<=1||j==i) continue;
                sum[j]-=2;
                for(int k=2;k<=14;k++) 
                {
                    if(sum[k]<=1||j==k) continue;
                    sum[k]-=2;
                    dfs(x+1);
                    sum[k]+=2;
                }
                sum[j]+=2;
            }
            sum[i]+=4;
        }
    }
    //把剩下的牌出完
    for(int i=2;i<=15;i++) if(sum[i]) x++;
    ans=min(ans,x);
}
int main() {
//  freopen("landlords.in","r",stdin);
//  freopen("landlords.out","w",stdout);
    scanf("%d%d",&T,&n);
    while(T--)
    {
        ans=0x7fffffff;
        int x,y;
        memset(sum,0,sizeof sum);
        for(int i=1;i<=n;i++)
        {
            scanf("%d%d",&x,&y);
            if (x==0) sum[15]++;//把
            else if(x==1) sum[14]++;
            else sum[x]++;
        }
        dfs(0);
        printf("%d\n",ans);
    }
}

好了,今天就到这里了,希望不会有下一次但是不可能的

posted @ 2019-07-11 19:45  盐渍番茄酱  阅读(110)  评论(0编辑  收藏  举报