A Infinity Gauntlet
不想说什么……emmm语法题??
#include<bits/stdc++.h>
using namespace std;
int n,m;
int exi[10];
char s[33];
int main(){
int i,j;
scanf("%d",&n);
for(i=1;i<=n;++i){
scanf("%s",s);
if(s[0]=='p'){
exi[1]=1;
}else if(s[0]=='g'){
exi[2]=1;
}else if(s[0]=='b'){
exi[3]=1;
}else if(s[0]=='o'){
exi[4]=1;
}else if(s[0]=='r'){
exi[5]=1;
}else if(s[0]=='y'){
exi[6]=1;
}
}
printf("%d\n",6-n);
if(!exi[1]) printf("Power\n");
if(!exi[2]) printf("Time\n");
if(!exi[3]) printf("Space\n");
if(!exi[4]) printf("Soul\n");
if(!exi[5]) printf("Reality\n");
if(!exi[6]) printf("Mind\n");
}
B High School: Become Human
取一个log,n次幂就变成了乘以n。
我们比较
和
就是比较
和
。
之前一直WA是因为本蒟蒻居然以为只有x==y时,才会有=的情况QWQ
然而 2 4 就是等于的,血WA…
最好不要用double变量存下来这个值,据说会被卡精度
#include<bits/stdc++.h>
#define db double
using namespace std;
int x,y,t;
int main(){
scanf("%d%d",&x,&y);
if(log(x)*y==log(y)*x){printf("=\n");}
else if(log(x)*y<log(y)*x) printf("<\n");
else printf(">\n");
}
C Three displays
dp贪心傻逼题
#include<bits/stdc++.h>
const int inf=2e9;
using namespace std;
int f[3010][3],n,c[3010],s[3010];
int ans=inf;
int main(){
int i,j;
scanf("%d",&n);
for(i=1;i<=n;++i){f[i][1]=f[i][2]=inf;scanf("%d",&s[i]);}
for(i=1;i<=n;++i) scanf("%d",&c[i]);
for(i=1;i<=n;++i){
f[i][0]=c[i];
for(j=1;j<i;++j){
if(s[j]<s[i]){
f[i][1]=min(f[i][1],f[j][0]+c[i]);
if(f[j][1]<inf){
f[i][2]=min(f[i][2],f[j][1]+c[i]);
}
}
}
}
for(i=3;i<=n;++i) ans=min(ans,f[i][2]);
if(ans>=inf) printf("-1\n");
else printf("%d\n",ans);
}
D Fair
…
我们直接k次bfs找到每个点离每种颜色最近的距离。求每个答案的时候sort把前s个加起来就好了。
本蒟蒻一开始血T…因为bfs的时候只加了一个dis=0的点进去跑(当然会血T),把所有加进去就过了。
#include<bits/stdc++.h>
using namespace std;
const int inf=2e9,N=1e5+5;
int d[N][102],a[N],n,k,cur,m,s,vis[N];
int head[N],to[N<<1],nxt[N<<1],tot,dir[102];
queue<int>Q;
vector<int>in[102];
inline int rd()
{
char ch=getchar();int x=0,f=1;
while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
while(isdigit(ch)){x=x*10+(ch^48);ch=getchar();}
return x*f;
}
inline void lk(int u,int v)
{to[++tot]=v;nxt[tot]=head[u];head[u]=tot;}
inline void bfs(int col)
{
int i,j,x;
for(i=in[col].size()-1;i>=0;i--){
j=in[col][i];Q.push(j);d[j][col]=0;vis[j]=1;
}
while(!Q.empty()){
x=Q.front();Q.pop();vis[x]=0;
for(i=head[x];i;i=nxt[i]){
j=to[i];
if(d[j][col]>d[x][col]+1){
d[j][col]=d[x][col]+1;
if(!vis[j]){
Q.push(j);
vis[j]=1;
}
}
}
}
}
int main(){
int i,j,x,y;
n=rd();m=rd();k=rd();s=rd();
for(i=1;i<=n;++i)
for(j=1;j<=k;++j)
d[i][j]=inf;
for(i=1;i<=n;++i) {a[i]=rd();in[a[i]].push_back(i);}
while(m--){x=rd();y=rd();lk(x,y);lk(y,x);}
for(i=1;i<=k;++i) bfs(i);
for(i=1;i<=n;++i){
cur=0;
sort(d[i]+1,d[i]+k+1);
for(j=1;j<=s;++j) cur+=d[i][j];
printf("%d ",cur);
}
}
E Petr and Permutations
这是一道水题。不过本蒟蒻考的时候还是血WA(可能是没有脑子吧)。
直接贪心找到最小交换多少次可以得到当前序列。
可知若剩下的操作次数为偶,则一定成立。
判一下3n减去当前次数是否为偶即可。
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+10;
int cnt,n,a[N],in[N];
int main(){
int i,j,t;
scanf("%d",&n);
for(i=1;i<=n;++i){scanf("%d",&a[i]);in[a[i]]=i;}
for(i=1;i<=n;++i){
if(a[i]!=i){
j=in[i];
a[j]=a[i];in[a[i]]=j;a[i]=i;
cnt++;
}
}
if((3*n-cnt)%2==0) printf("Petr\n");
else printf("Um_nik\n");
}
F AND Graph
全集当然为2^n-1。
一开始的思路是1-n枚举,枚举每个数异或全集的子集(就是可以连的数),同一个自己的用并查集连起来。最后查一下有多少了独立集就好了。
果不其然TLE…
后来发现并不需要这么麻烦,我们处理前面的数时会连到后面的数,处理后面的数时再返回来又会重复处理多次。
其实我们只需要O(n)dfs一遍就好了
#include<bits/stdc++.h>
using namespace std;
const int N=(1<<22)+10;
int n,m,exi[N],a[N],v[N],ans,al;
inline void dfs(int x)
{
if(v[x]) return;
v[x]=1;
if(exi[x]) dfs(al^x);
for(int i=0;i<n;++i){
if(x&(1<<i)){
dfs(x^(1<<i));
}
}
}
int main(){
int i,j,cur,now,q,p;
scanf("%d%d",&n,&m);al=(1<<n)-1;
for(i=1;i<=m;++i){scanf("%d",&a[i]);exi[a[i]]=1;}
for(i=1;i<=m;++i){
if(!v[a[i]]){ans++;v[a[i]]=1;dfs(al^a[i]);}
}
printf("%d\n",ans);
}
这场真是水题大放送…
大家快来AK全场吧(雾