NOIP2015-day1

T1
方格填数:模拟就好了

注意边界,还有看清楚题目,是右上方,a[hk-1][lk+1]
不是左上方,QAQ

#include<iostream>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<string>
#include<vector>
#include<queue>
#include<map>
#include<set>
#include<algorithm>
#ifdef WIN32
#define AUTO "%I64d"
#else 
#define AUTO "%lld"
#endif
using namespace std;
#define max(x,tmp) x=max(x,tmp)
#define min(x,tmp) x=min(x,tmp)
#define maxx(x1,x2,x3) max(x1,max(x2,x3))
#define minn(x1,x2,x3) min(x1,min(x2,x3))
const int INF=0x3f3f3f3f;
inline int readin(){
    int res=0;
    char ch;
    while((ch = getchar())<'0'||ch>'9');
    res=ch-'0';
    while((ch = getchar())>='0'&&ch<='9')
        res=res*10+ch-'0';
    return res;
}
int n;
int a[45][45];
int main(){
    freopen("magic.in","r",stdin);
    freopen("magic.out","w",stdout);
    n=readin();
    int hk,lk;
    a[1][(n+1)/2]=1;
    hk=1,lk=(n+1)/2;
    for(int i = 2; i <= n*n; i++){
        if(hk == 1 && lk!= n){a[n][lk+1]=i,hk=n,lk=lk+1;continue;}
        if (hk != 1 && lk ==n){a[hk-1][1]=i,hk=hk-1,lk=1;continue;}
        if(hk == 1 && lk == n){a[hk+1][lk]=i,hk++;continue;}
        if(hk!=1 && lk!=n){
                if(a[hk-1][lk+1]==0&&hk-1>=1&&lk+1<=n){a[hk-1][lk+1]=i,hk--,lk++;continue;}
                else {a[hk+1][lk]=i,hk++;continue;}
        }
    }
    for(int i = 1; i <= n;i++){
        for(int j = 1; j <= n;j++)
            printf("%d ",a[i][j]);
        printf("\n");
    }
    return 0;
}

T2
信息传递:听说可以爆搜,不过我写的tarjian,求最小环,不包括一个的。

#include<iostream>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<string>
#include<vector>
#include<queue>
#include<map>
#include<set>
#include<algorithm>
#ifdef WIN32
#define AUTO "%I64d"
#else 
#define AUTO "%lld"
#endif
using namespace std;
#define LL long long
#define max(x,tmp) x=max(x,tmp)
#define min(x,tmp) x=min(x,tmp)
#define maxx(x1,x2,x3) max(x1,max(x2,x3))
#define minn(x1,x2,x3) min(x1,min(x2,x3))
const int INF=0x3f3f3f3f;
const int N = 200010;
struct ii{
    int to,ne;
    ii(int to = 0,int ne = 0):to(to),ne(ne){}
}ed[N];
int Index,DNF[N],Low[N],Stack[N],top,head[N],ans=INF,n;
bool Instack[N];

inline int readin(){
    int res =0 ;
    char ch;
    while((ch = getchar())<'0'||ch>'9');
    res=ch-'0';
    while((ch = getchar())>='0'&&ch<='9')
        res=res*10+ch-'0';
    return res;
}
void tarjian(int i){
    DNF[i]=Low[i]=++Index;
    Stack[++top]=i;
    Instack[i]=true;
    for(int o = head[i];o;o=ed[i].ne){
        int j=ed[o].to;
        if(!DNF[j]){
            tarjian(j);
            min(Low[i],Low[j]);
        }
        else if(Instack[j])
            min(Low[i],DNF[j]);
    }
    if(DNF[i] == Low[i]){
        int u=0,sum=0;
        while(u!=i){
            u=Stack[top--];
            Instack[u]=false;
            sum++;
        }
        if(sum != 1)min(ans,sum);
    }
}

void work(){
    for(int i = 1; i<= n; i++)
        if(!DNF[i])
            tarjian(i);
}
int a[N];
int main(){
    freopen("message.in","r",stdin);
    freopen("message.out","w",stdout);
    n=readin();
    for(int i =1; i<= n; i++)a[i]=readin();
    for(int i = 1; i <= n; i++){
        ed[i]=ii(a[i],head[i]);
        head[i]=i;
    }
    work();
    printf("%d\n",ans);
    return 0;
}

T3:斗地主
写的自己写的记忆化,后来调不出来,就全盘否定了。。QAQ
某神的算法,,
预处理,4,3的
然后再搜索,神!!!,注意王的情况,可以出对王,但是不能带对王。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<map>
#include<queue>
#include<set>
#include<algorithm>
#include<string>
#ifdef WIN32
#define AUTO "%I64d"
#else
#define AUTO "%lld"
#endif
using namespace std;
#define smin(x,temp) x=min(x,temp)
#define smax(x,temp) x=max(x,temp)
#define minn(x1,x2,x3) min(x1,min(x2,x3))
#define maxx(x1,x2,x3) max(x1,max(x2,x3))
const int INF=0x3f3f3f3f;
int ans,tot[6],T,n,cnt[20];
inline int readin(){
    int res= 0;
    char ch;
    while((ch= getchar())>'9'||ch<'0');
    res=ch-'0';
    while((ch = getchar())<='9'&&ch>='0')
            res=res*10+ch-'0';
    return res;
}
inline void init(){
    memset(cnt,0,sizeof(cnt));
    for(int i = 1; i <= n; i++){
        int x=readin(),y=readin();
        if(x==1)x=14;
        if(!x)x++;
        cnt[x]++;
    }
    ans=INF;
}
int cala(){//预处理
    int ret=0;
    int flag = (cnt[1] == 2);//wang
    memset(tot,0,sizeof(tot));
    for(int i = 1; i<=14;i++)tot[cnt[i]]++;
    while(tot[4] && tot[2]>=2)ret++,tot[4]--,tot[2]-=2;//4带两对
    while(tot[4] && tot[1]>=2)ret++,tot[4]--,tot[1]-=2;
    while(tot[3] && tot[2]-flag)ret++,tot[3]--,tot[2]--;
    while(tot[3] && tot[1])ret++,tot[3]--,tot[1]--;
    return ret + tot[4] + tot [3] +tot[2] + tot[1];
}
void dfs(int step){
    if(step > ans)return;
    smin(ans,step+cala());
    for(int i = 3;i <= 14; i++){
        if(cnt[i]<3)continue;
        int j =i;
        while(cnt[j+1]>=3)j++;
        if(j-i+1>2)continue;
        for(int o = i ; o<= j; o++)cnt[o]-=3;
        for(int o = j ; o>=i; o--){
            if(o-i+1>=2)dfs(step+1);
            cnt[o] +=3;
        }
    }
    for(int i = 3;i<= 14;i++){//姐妹对
        if(cnt[i]<2)continue;
        int j= i;
        while(cnt[j+1]>=2)j++;
        if(j-i+1<3)continue;
        for(int o = i; o <= j;o++)cnt[o]-=2;
        for(int o =j; o>=i;o--){
            if(o-i+1>=3)dfs(step+1);
            cnt[o]+=2;
        }
    }
    for(int i = 3; i <= 14; i++){
        if(cnt[i]<1)continue;
        int j =i;
        while(cnt[j+1]>=1)j++;
        if(j-i+1<5)continue;
        for(int o = i; o <=j; o++)cnt[o]--;
        for(int o =j ;o >=i;o--){
            if(o-i+1>=5)dfs(step+1);
            cnt[o]++;
        }
    }
}
int main(){
    freopen("landlords.in","r",stdin);
    freopen("landlords.out","w",stdout);
    T=readin(),n=readin();
    for(int i = 1; i <= T;i++){
        init();
        dfs(0);
        printf("%d\n",ans);
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值