【比赛报告】2018.10.24校赛[长乐一中Day1] NOIP练习赛卷二十一

xiaoxiao2025-06-10  13


#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int N=3e4+10,M=5e2+10,sed=31,SED=131,mod=70177,MOD=92311; int n,m,p,q,ans,tot,hd[mod],nx[N*2],ver[N*2],cnt[N*2],Hash[N],HASH[N]; struct node{ char s[M]; inline bool operator<(const node&rhs)const{ return strcmp(s,rhs.s)<0;} }a[N]; inline void Insert(const int &x,const int &y) { for(int i=hd[x];i;i=nx[i]) if(ver[i]==y){++cnt[i];return;} nx[++tot]=hd[x];hd[x]=tot;ver[tot]=y;cnt[tot]=1; return; } inline int query(const int &x,const int &y) { for(int i=hd[x];i;i=nx[i]) if(ver[i]==y)return cnt[i]; return 0; } inline void solve1() { int tmp,TMP;ans=-1; for(int i=0;i<n;i++) { tmp=TMP=0; for(int j=0;j<m;j++) { tmp=(tmp*sed+(a[i].s[j]=='N'))%mod; TMP=(TMP*SED+(a[i].s[j]=='N'))%MOD; } Hash[i]=tmp,HASH[i]=TMP; Insert(tmp,TMP); } for(int i=0;i<n;i++) if(query(Hash[i],HASH[i])==p)//当成满分有p个 { tmp=TMP=0; for(int j=0;j<m;j++)//求出零分答案 { tmp=(tmp*sed+(a[i].s[j]=='Y'))%mod; TMP=(TMP*SED+(a[i].s[j]=='Y'))%MOD; } if(query(tmp,TMP)==q){ans=i;break;}//符合题意 } if(ans!=-1)printf("%s\n",a[ans].s); else puts("-1"); return; } char cur[M]; inline void solve2() { int tmp,TMP;ans=-1; for(int i=0;i<n;i++) { tmp=TMP=0; for(int j=0;j<m;j++) { tmp=(tmp*sed+(a[i].s[j]=='N'))%mod; TMP=(TMP*SED+(a[i].s[j]=='N'))%MOD; } Hash[i]=tmp,HASH[i]=TMP; Insert(tmp,TMP); } for(int i=n-1;i>=0;i--)//枚举零分答案,所以字典序要反着来 if(query(Hash[i],HASH[i])==q) { tmp=TMP=0; for(int j=0;j<m;j++) { tmp=(tmp*sed+(a[i].s[j]=='Y'))%mod; TMP=(TMP*SED+(a[i].s[j]=='Y'))%MOD; } if(query(tmp,TMP)==p){ans=i;break;} } if(ans!=-1) { for(int i=0;i<m;i++) cur[i]=a[ans].s[i]=='N'?'Y':'N'; printf("%s\n",cur); } else puts("-1"); return; } inline void solve3() { int tmp,TMP; for(int i=0;i<n;i++) { tmp=TMP=0; for(int j=0;j<m;j++) { tmp=(tmp*sed+(a[i].s[j]=='N'))%mod; TMP=(TMP*SED+(a[i].s[j]=='N'))%MOD; } Insert(tmp,TMP); tmp=TMP=0; for(int j=0;j<m;j++) { tmp=(tmp*sed+(a[i].s[j]=='Y'))%mod; TMP=(TMP*SED+(a[i].s[j]=='Y'))%MOD; } Insert(tmp,TMP); } bool flag=true; for(int i=0;i<m;i++)cur[i]='N'; do{ tmp=TMP=0; for(int j=0;j<m;j++) { tmp=(tmp*sed+(cur[j]=='N'))%mod; TMP=(TMP*SED+(cur[j]=='N'))%MOD; } if(query(tmp,TMP)==0){flag=true;break;}//没有在满分和零分里面出现过 flag=false; for(int j=m-1;j>=0;j--) { if(cur[j]=='Y')cur[j]='N';//已经修改过一次的部分无解 else{cur[j]='Y';flag=true;break;}//没有修改的给它修改了,可能存在解 } }while(flag); if(flag)printf("%s\n",cur); else puts("-1"); return; } int main() { //freopen("in.txt","r",stdin); scanf("%d%d%d%d",&n,&m,&p,&q); for(int i=0;i<n;i++) scanf("%s",a[i].s); sort(a,a+n); if(p)solve1(); else if(q)solve2(); else solve3(); return 0; }


#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int N=1001; const int M=1024; const int power=9; const int base=1e9; struct Bignum{ int a[50]; Bignum(){memset(a,0,sizeof(a));} void print() { printf("%d",a[a[0]]); for(int i=a[0]-1;i>0;i--) printf("%0*d",power,a[i]); printf("\n"); } void add(int k){if(k||a[0])a[++a[0]]=k;} }f[2][M][3]; Bignum operator +(const Bignum&p,const Bignum&q) { Bignum c; c.a[0]=max(p.a[0],q.a[0]); for(int i=1;i<=c.a[0];i++) { c.a[i]+=p.a[i]+q.a[i]; c.a[i+1]+=c.a[i]/base; c.a[i]%=base; } if(c.a[c.a[0]+1])c.a[0]++; return c; } int n,a[N],pre,cur; int main() { //freopen("in.txt","r",stdin); scanf("%d",&n); for(int i=n;i;i--) scanf("%d",&a[i]); f[0][1023][0].add(1); for(int i=0;i<n;i++) { cur=pre^1; for(int j=0;j<M;j++) for(int k=0;k<=2;k++) f[cur][j][k]=f[pre][j][k]; for(int j=0;j<M;j++) { f[cur][j&a[i+1]][1]=f[cur][j&a[i+1]][1]+f[pre][j][0];f[cur][j&a[i+1]][1]=f[cur][j&a[i+1]][1]+f[pre][j][1]; f[cur][j^a[i+1]][2]=f[cur][j^a[i+1]][2]+f[pre][j][1];f[cur][j^a[i+1]][2]=f[cur][j^a[i+1]][2]+f[pre][j][2]; } pre^=1; } f[pre][0][2].print(); return 0; }


#include<cstdio> #include<queue> #include<cstring> #include<algorithm> using namespace std; #define MP(a,b) make_pair(a,b) typedef long long ll; typedef pair<int,int> pii; template<class T>inline void read(T&x) { x=0;int f=0;char ch=getchar(); while(ch<'0'||ch>'9')f|=ch=='-',ch=getchar(); while(ch>='0'&&ch<='9')x=(x<<1)+(x<<3)+(ch^48),ch=getchar(); if(f)x=-x; } const int N=51,M=201,K=20001; int Case,n,m,tot,hd[N],len; ll T,dis[N][K];//dis[i][j]表示到达i号点,时间为j+p*2d,最小的j+p*2d bool vis[N][K]; struct Edge{ int v,nx,w; }e[M]; inline void add(int u,int v,int w) { e[++tot].v=v; e[tot].nx=hd[u]; e[tot].w=w; hd[u]=tot; } inline void spfa() { memset(dis,0x3f,sizeof(dis)); dis[0][0]=0;queue<pii>q;q.push(MP(0,0)); while(q.size()) { pii tmp=q.front();q.pop(); int u=tmp.first,w=tmp.second;vis[u][w]=false; for(int i=hd[u];i;i=e[i].nx) { int v=e[i].v;int neww=dis[u][w]+e[i].w; if(dis[v][neww%len]>neww) { dis[v][neww%len]=neww; if(!vis[v][neww%len]) { vis[v][neww%len]=1;q.push(MP(v,neww%len)); } } } } } int main() { //freopen("in.txt","r",stdin); read(Case); while(Case--) { read(n);read(m);read(T); memset(hd,0,sizeof(hd));tot=0; for(int i=1,u,v,w;i<=m;i++) read(u),read(v),read(w),add(u,v,w),add(v,u,w); if(!hd[0])puts("Impossible"); else { len=10001; for(int i=hd[0];i;i=e[i].nx) len=min(len,e[i].w); len*=2;spfa(); if(dis[n-1][T%len]<=T)puts("Possible"); else puts("Impossible"); } } return 0; }

赛后总结

T1又开始瞎JB乱想,在那里琢磨怎么确定每个问题的解……其实直接枚举每个解为正解或0分就可以了。 T2最开始写的是顺着扫一遍倒着扫一遍再枚举分点的DP,又是莫名其妙的错了。 T3也是感觉非常的迷,没想到这种做法。 或许我真的就只是嘴硬吧。三道题都有人AC,我却都不行。感觉他们在不停的进步,我却连门都没摸到。 或许我真的就只是嘴硬吧。

转载请注明原文地址: https://www.6miu.com/read-5031582.html

最新回复(0)