1001:2048
很明显,一开始看错题了。。。sad
这题目我感觉挺卡时间的。。。
dp[i][j]:在选择2^i的时候,选择的和为j*2^i到(j+1)*2^i-1时候的情况。
#include <iostream> #include<stdio.h> #include<vector> #include<queue> #include<stack> #include<string.h> #include<algorithm> #include<math.h> using namespace std; #define LL __int64 #define lcm(a,b) (a*b/gcd(a,b)) #define mod 998244353 #define maxn 110000 //O(n)求素数,1-n的欧拉数 int num[21]; LL dp[15][2100]; LL jie[maxn]; LL use[15][2100]; int n; int add(int x) { if(x==0)return 20; int c=0; while(x!=1) { if(x&1)return 20; x=x>>1; c++; } return c; } LL q_mod(LL a,LL b,LL n) { LL ret=1; LL tmp=a%n; while(b) { //基数存在 if(b&0x1) ret=ret*tmp%n; tmp=tmp*tmp%n; b>>=1; } return ret; } LL select(int n,int m) { if(m>n)return 0; LL ans=jie[n]; ans=(ans*q_mod((jie[m]*jie[n-m])%mod,mod-2,mod))%mod; return ans; } void select() { for(int i=1;i<=11;i++) { for(int j=0;j<2048;j++) { use[i][j]=select(num[i-1],j); } } } void dos() { select(); for(int j=0;j<2048;j++)dp[1][j]=use[1][j]; for(int i=2; i<12; i++) { int cnt=1<<(12-i); for(int j=0; j<cnt; j++) { for(int k=0; k<=j*2+1; k+=2) { dp[i][j]+=((dp[i-1][k]+dp[i-1][k+1])*use[i][j-k/2])%mod; } dp[i][j]%=mod; } } LL ans=0; ans=q_mod(2,num[20],mod); LL ps=(dp[11][0]+dp[11][1])%mod; ps=q_mod(2,n-num[20],mod)-ps; ps=(ps+mod)%mod; ans=(ans*ps)%mod; cout<<ans<<endl; } int main() { //freopen("1001.in","r",stdin); //freopen("10011.out","w",stdout); int cas=0; int x; jie[0]=1; for(int i=1; i<maxn; i++)jie[i]=(jie[i-1]*i)%mod; while(~scanf("%d",&n)&&n) { memset(num,0,sizeof(num)); memset(dp,0,sizeof(dp)); cas++; for(int i=1; i<=n; i++) { scanf("%d",&x); num[add(x)]++; } printf("Case #%d: ",cas); dos(); } return 0; }
1004:Kingdom
超级后悔当时没有看这个题。。。。明显水题嘛。。。。
相当于拓扑排序。。
每次弹出入度最小的点。根本没有-1的情况。。。被骗了。。。
#include <iostream> #include<stdio.h> #include<vector> #include<queue> #include<stack> #include<string.h> #include<algorithm> #include<math.h> using namespace std; #define LL long long #define lcm(a,b) (a*b/gcd(a,b)) //O(n)求素数,1-n的欧拉数 #define maxn 505 int mp[maxn][maxn]; vector<int>vec; int du[maxn]; int n; void tuopu() { vec.clear(); int i; while(1) { int now=0; int minn=9999; for(i=1;i<=n;i++) { if(du[i]>=0&&minn>du[i]) { now=i; minn=du[i]; } } if(now==0)break; vec.push_back(now); du[now]=-1; for(i=1;i<=n;i++) { if(mp[i][now])du[i]--; } } if(vec.size()<n)cout<<"-1"<<endl; else { for(int i=vec.size()-1;i>=0;i--) { printf("%d",vec[i]); if(i!=0)printf(" "); else puts(""); } } } char str[11001]; int main() { LL p,g,y; //freopen("1004.in","r",stdin); // freopen("10041.out","w",stdout); while(~scanf("%d",&n)&&n) { memset(du,0,sizeof(du)); for(int i=1;i<=n;i++) { scanf("%s",str); for(int j=1;j<=n;j++) { mp[i][j]=str[j-1]-'0'; if(mp[i][j])du[i]++; } } tuopu(); } return 0; }
1007:Multiplication table
整场比赛最伤的就是这个题,一开始思路有问题,后来就一直带偏了。。。
很明显,对于不同的数,首位的类别有不同种。
#include <iostream> #include<stdio.h> #include<vector> #include<queue> #include<stack> #include<string.h> #include<algorithm> #include<math.h> using namespace std; #define LL long long #define lcm(a,b) (a*b/gcd(a,b)) //O(n)求素数,1-n的欧拉数 int mp[2][505][505]; vector<int>vec[505]; int ans[505]; int num[505]; int in() { char ch; int a = 0; while((ch = getchar()) == ' ' || ch == '\n'); a += ch - '0'; while((ch = getchar()) != ' ' && ch != '\n') { a *= 10; a += ch - '0'; } return a; } int main() { // freopen("1007.in","r",stdin); // freopen("10071.out","w",stdout); int x,y; int cas=0; int check[101]; int n; while(~scanf("%d",&n)&&n) { cas++; memset(ans,-1,sizeof(ans)); for(int i=0; i<n; i++) { for(int j=0; j<n; j++) { x=in(); y=in(); mp[0][i][j]=x; mp[1][i][j]=y; if(x==y&&x==i&&i==j) { ans[0]=i; } } } for(int i=0; i<n; i++) { if(mp[0][i][i]==ans[0]&&mp[1][i][i]!=ans[0]&&mp[1][i][i]==i) { ans[1]=i; break; } } for(int i=0; i<n; i++) { vec[i].clear(); for(int j=0; j<n; j++)vec[i].push_back(mp[0][i][j]); sort(vec[i].begin(),vec[i].end()); num[i]=1; for(int j=1; j<vec[i].size(); j++) { if(vec[i][j]!=vec[i][j-1])num[i]++; } if(num[i]>1)ans[num[i]]=i; } printf("Case #%d:",cas); int leap=0; for(int i=0; i<n; i++) { printf(" %d",ans[i]); if(ans[i]==-1)leap=1; } while(leap) { cout<<check[110101010110]<<endl; } cout<<endl; } return 0; }
2014多校联合-第八场
时间: 2024-09-29 22:19:57