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;
}