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; }
/* 题意不好懂,自行体会。 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]) ; }
折花枝,恨花枝,准拟花开人共卮,开时人去时。
怕相思,已相思,轮到相思没处辞,眉间露一丝。