10.9NOIP模拟题

 

/*
big模拟
细节不少
remove表示这个玩意儿在这一秒有没有移动
注意在一秒内所有小葱一起移动,所以如果一个一个处理
别忘了“错位”这种情况
*/
#include<iostream>
#include<cstdio>
#include<cstring>

#define N 1001

using namespace std;
int n,m,T,k,ans;
int belong[N][N],cnt[N][N];
struct C{
    int x,y,flag1,turn,f,remove;
}p[N];

inline int read()
{
    int x=0,f=1;char c=getchar();
    while(c>'9'||c<'0'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
    return x*f;
}

bool can(int x)
{
    if(p[x].remove==1) return true;
    if(p[x].x==1 && p[x].turn==0) return true;
    if(p[x].x==n && p[x].turn==1) return true;
    if(p[x].y==1 && p[x].turn==2) return true;
    if(p[x].y==m && p[x].turn==3) return true;
    return false;
}

void judge(int i,int o)
{
    if(cnt[p[i].x][p[i].y])
    {
        if(can(belong[p[i].x][p[i].y]))
        {
            if(p[belong[p[i].x][p[i].y]].f>p[i].f) p

[i].flag1=1;
            else p[belong[p[i].x][p[i].y]].flag1=1,belong

[p[i].x][p[i].y]=i;
        }
        else 
        {
              belong[p[i].x][p[i].y]=i;
              cnt[p[i].x][p[i].y]++;    
        }
    }
    else
    { 
      belong[p[i].x][p[i].y]=i;
      cnt[p[i].x][p[i].y]++;    
    } 
}

int main()
{
    freopen("problem.in","r",stdin);
    freopen("problem.out","w",stdout);    
    n=read();m=read();k=read();
    for(int i=1;i<=k;i++) p[i].x=read(),p[i].y=read(),
    p[i].turn=read(),p[i].f=read();
    T=read();
    for(int i=1;i<=k;i++) 
    belong[p[i].x][p[i].y]=i,cnt[p[i].x][p[i].y]++;
    
    while(T--)
    {
        for(int i=1;i<=k;i++) p[i].remove=0;
        for(int i=1;i<=k;i++)
        {
            if(p[i].flag1) continue;
            if(p[i].turn==0)
            {
                if(p[i].x>1)
                {
                    cnt[p[i].x][p[i].y]--;
                    if(belong[p[i].x][p[i].y]==i)
                    belong[p[i].x][p[i].y]=0;
                    p[i].x--;
                    judge(i,0);p[i].remove=1;
                }
                else {p[i].turn=1;p

[i].remove=1;continue;}
            }
            if(p[i].turn==1)
            {
                if(p[i].x<n)
                {
                    cnt[p[i].x][p[i].y]--;
                    if(belong[p[i].x][p[i].y]==i)
                    belong[p[i].x][p[i].y]=0;
                    p[i].x++;
                    judge(i,1);p[i].remove=1;
                }
                else {p[i].turn=0;p[i].remove=1;continue;}
            }
            if(p[i].turn==2)
            {
                if(p[i].y>1)
                {
                    cnt[p[i].x][p[i].y]--;
                    if(belong[p[i].x][p[i].y]==i)
                    belong[p[i].x][p[i].y]=0;
                    p[i].y--;
                    judge(i,2);p[i].remove=1;
                }
                else {p[i].turn=3;p

[i].remove=1;continue;}
            }
            if(p[i].turn==3)
            {
                if(p[i].y<m)
                {
                    cnt[p[i].x][p[i].y]--;
                    if(belong[p[i].x][p[i].y]==i)
                    belong[p[i].x][p[i].y]=0;
                    p[i].y++;
                    judge(i,3);p[i].remove=1;
                }
                else {p[i].turn=2;p

[i].remove=1;continue;}
            }
        }
    }
    for(int i=1;i<=k;i++) printf("%d %d\n",p[i].x,p[i].y);
    fclose(stdin);fclose(stdout);
    return 0;
}

 

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>

using namespace std;

const int maxn=110;
const int maxk=1010;

int n,m,k,x[maxk],y[maxk],d[maxk],f[maxk],z[maxk],t;

bool alive[maxk];

int dx[4],dy[4];

void move(int p)
{
    x[p] += dx[d[p]];
    y[p] += dy[d[p]];
    if (x[p]<1 || x[p]>n || y[p]<1 || y[p]>m)
    {
        x[p] -= dx[d[p]];
        y[p] -= dy[d[p]];
        d[p] ^= 1;
    }
}

bool cmp(int a,int b)
{
    if (x[a]!=x[b]) return x[a]<x[b];
    else return y[a]<y[b];
}

int main()
{
    dx[0]=-1;dx[1]=1;dy[2]=-1;dy[3]=1;
    scanf("%d%d%d",&n,&m,&k);
    for (int a=1;a<=k;a++)
        scanf("%d%d%d%d",&x[a],&y[a],&d[a],&f[a]);
    for (int a=1;a<=k;a++)
    {
        alive[a]=true;
        z[a]=a;
    }
    scanf("%d",&t);

    for (;t--;)
    {
        for (int a=1;a<=k;a++)
            if (alive[a]) move(a);
        sort(z+1,z+k+1,cmp);

        for (int a=1;a<=k;)
        {
            int b=a,p=-1;
            while (x[z[b]]==x[z[a]] && y[z[b]]==y[z[a]] && b<=k)
            {
                if (alive[z[b]] && (p==-1 || f[z[b]]>f[z[p]])) p=b;
                b++;
            }
            for (int c=a;c<b;c++)
                if (p!=-1 && c!=p) alive[z[c]]=false;
            a=b;
        }
    }
    for (int a=1;a<=k;a++)
        printf("%d %d\n",x[a],y[a]);

    return 0;
}
知道自己代码丑 std0.0

 

/*
题意不好懂,自行体会。
20暴力 dfs
加剪枝可能会多跑过两个点
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<map>

#define mod 12345

#define N 9001
using namespace std;
int n,m,flag;
long long ans;
char c[N],cur[N];
int b[N],vis[N];
map<char,int>cnt;

inline int read()
{
    int x=0,f=1;char c=getchar();
    while(c>'9'||c<'0'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
    return x*f;
}

void dfs(int now)
{
    if(now==n+1)
    {
        for(int i=1;i<=m;i++) cnt[c[i]]=0;
        flag=0;
        for(int i=1;i<=n;i++) cnt[cur[i]]++;
        for(int i=1;i<=m;i++)
        if(cnt[c[i]]%b[i] && cnt[c[i]]) flag=1;
        if(!flag) ans++,ans%=mod;
        return;
    }
    for(int i=1;i<=m;i++) 
    {
        if(!vis[now]) vis[now]=1,cur[now]=c[i];
        dfs(now+1);vis[now]=0;
    }
}

int main()
{
    freopen("too.in","r",stdin);
    freopen("too.out","w",stdout);
    n=read();m=read();
    for(int i=1;i<=m;i++) cin>>c[i]>>b[i];
    dfs(1);ans%=mod;
    printf("%lld\n",ans);
    return 0;
}

 

 

 

/*
30暴力
bitset预处理任意两点间边数 e[i][j]
然后dp dp[i]表示1->i路径数
dp[i+1]=Σdp[j]*e[j][i+1] (j<=i)
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<bitset>

#define N 1007
#define mod 991127
#define ll long long 

using namespace std;
bitset<33>a;
bitset<33>b;
bitset<33>c;
int n,m,num[N];
ll e[N][N],dp[N];

inline int read()
{
    int x=0,f=1;char c=getchar();
    while(c>'9'||c<'0'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
    return x*f;
}

int main()
{
    freopen("easy.in","r",stdin);
    freopen("easy.out","w",stdout);
    n=read();
    for(int i=1;i<=n;i++) num[i]=read();
    for(int i=1;i<=n;i++)  for(int j=i+1;j<=n;j++)
    {
        a=num[i];b=num[j];c=a&b;
        e[i][j]=c.count();e[i][j]%=mod;
    }
    dp[1]=1;ll tmp=0;
    for(int i=1;i<n;i++)
    {
        tmp=0;
        for(int j=1;j<=i;j++)
        {
            tmp+=(dp[j]*e[j][i+1])%mod;
            tmp%=mod;
        }
        dp[i+1]+=tmp;dp[i+1]%=mod;
    }
    dp[n]%=mod;
    printf("%lld\n",dp[n]);
    return 0;
}
/*
注意题目要求只能编号小的往大的连边
f[i]表示第i位是1的数的贡献,编号由小到大类似前缀和累计
先枚举每个点权
如果当前点第i位是1的话,那能转移到它的位置也一定是1
然后再把当前位置的贡献加上
*/
#include <bits/stdc++.h>

#define MOD 991127

using namespace std ;

int n ; 

const int MAXN = 200010 ;

int a[MAXN];

int f[30] ;

int dp[MAXN] ; 

inline void update(int &a, int b) {
        a += b ;
        if (a >= MOD) a -= MOD ; 
}
int main() { 

        scanf("%d", &n) ; 
        for (int i = 1; i <= n; i ++) { 
                scanf("%d", &a[i]) ; 
        }

        memset(f, 0, sizeof f); 

        for (int i = 0; i < 30; i ++) { 
                if ((a[1] >> i) & 1) f[i] = 1;  
        }
        dp[1] = 1 ; 
        for (int i = 2; i <= n; i ++) { 
                for (int j = 0; j < 30; j ++) { 
                        if ((a[i] >> j) & 1) 

update(dp[i], f[j]) ; 
                }
                for (int j = 0; j < 30; j ++) { 
                        if ((a[i] >> j) & 1) 

update(f[j], dp[i]) ; 
                }
        }

        printf("%d\n", dp[n]) ; 

}

 

posted @ 2018-10-09 14:47  安月冷  阅读(184)  评论(0编辑  收藏  举报