做virtual judge时的代码,感觉有点挫,随便贴一下吧,继续切博弈。
A题 模拟题
这题本身还是非常水的。写的时候要注意题意,队友读的题意我写了很久调不出来,最后慢慢读题了才一个个错误地改出来了。
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <map>
using namespace std;
map<string,int>mp;
void init()
{
mp["1m"]=1; mp["1s"]=11; mp["1p"]=21;
mp["2m"]=2; mp["2s"]=12; mp["2p"]=22;
mp["3m"]=3; mp["3s"]=13; mp["3p"]=23;
mp["4m"]=4; mp["4s"]=14; mp["4p"]=24;
mp["5m"]=5; mp["5s"]=15; mp["5p"]=25;
mp["6m"]=6; mp["6s"]=16; mp["6p"]=26;
mp["7m"]=7; mp["7s"]=17; mp["7p"]=27;
mp["8m"]=8; mp["8s"]=18; mp["8p"]=28;
mp["9m"]=9; mp["9s"]=19; mp["9p"]=29;
mp["1c"]=31;mp["2c"]=32; mp["3c"]=33;
mp["4c"]=34;mp["5c"]=35; mp["6c"]=36;
mp["7c"]=37;
}
int cnt[40],arr[40],www[40];
bool isok()
{
for(int i=0;i<40;i++) if(cnt[i]>4) return 0;
return 1;
}
bool jud0()
{
for(int i=1;i<38;i++) arr[i]=www[i];
for(int i=1;i<38;i++)
{
if(arr[i]>=3) arr[i]-=3;
if(arr[i])
{
if(i>30) return 0;//选顺子时不能在c类型里选择
if(arr[i+1]<arr[i]||arr[i+2]<arr[i]) return 0;
else arr[i+1]-=arr[i],arr[i+2]-=arr[i],arr[i]=0;
}
}
return 1;
}
bool jud1()
{
for(int i=1;i<38;i++) www[i]=cnt[i];
for(int i=1;i<38;i++) if(www[i]>=2)//居然是要选择两个相同的
{
www[i]-=2;
if(jud0())return 1;
www[i]+=2;
}
return 0;
}
bool jud2()
{
int ans=0;
for(int i=0;i<40;i++) if(cnt[i]==2) ans++;
return ans==7;
}
bool jud3()
{
int a=0,b=0;
if(cnt[1]==1) a++; if(cnt[1]==2) b++;
if(cnt[9]==1) a++; if(cnt[9]==2) b++;
if(cnt[11]==1) a++; if(cnt[11]==2) b++;
if(cnt[19]==1) a++; if(cnt[19]==2) b++;
if(cnt[21]==1) a++; if(cnt[21]==2) b++;
if(cnt[29]==1) a++; if(cnt[29]==2) b++;
for(int i=31;i<38;i++)//居然可以在c类型中选择
{
if(cnt[i]==1) a++;
if(cnt[i]==2) b++;
}
return a==12&&b==1;
}
void out(int x)
{
putchar(' ');
putchar(x%10+48);
if(x<10) putchar('m');
else if(x<20) putchar('s');
else if(x<30) putchar('p');
else putchar('c');
}
int main()
{
//freopen("in","r",stdin);
int t=1;init();
scanf("%d",&t);
while(t--)
{
memset(cnt,0,sizeof(cnt));
char s[10];
for(int i=0;i<13;i++)
{
scanf("%s",s);
cnt[mp[s]]++;
}
bool fg;
vector<int>ans;
for(int i=1;i<38;i++)
{
if(i==10||i==20||i==30) continue;
cnt[i]++;fg=isok();
if(!fg){cnt[i]--; continue;}
if(jud3()||jud2()||jud1()) ans.push_back(i);
cnt[i]--;
}
if(ans.size())
{
sort(ans.begin(),ans.end());
printf("%d",ans.size());
for(int i=0;i<ans.size();i++) out(ans[i]);puts("");
}
else puts("Nooten");
}
return 0;
}
B题 数论水题
根号N枚举出因子计算一下。
#include<iostream>
using namespace std;
typedef long long ll;
ll g(ll x,ll m)
{
ll ans=0;
while(x)
{
ll tmp=x%m;
ans+=tmp*tmp;
x/=m;
}
return ans;
}
void out(ll x,ll m)
{
char s[20];
int i=19;s[i]=0;
while(x)
{
int tmp=x%m;
s[--i]=tmp<10?tmp+48:tmp+65-10;
x/=m;
}
cout<<s+i<<endl;
}
int main()
{
ll n,m;
while(cin>>n>>m)
{
ll ans=0;
for(ll i=1;i*i<=n;i++) if(n%i==0)
{
ans+=g(i,m);
if(i*i!=n) ans+=g(n/i,m);
}
out(ans,m);
}
return 0;
}
C题 DP题
注意向上旋转的情况的转移。dp[i][j][k]表示前i位相同且第i+1位增加为j ,i+2位增加为k的状态 对应的最小转动次数。
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int dp[1111][11][11];
char a[1111],b[1111];
int main()
{
while(scanf("%s%s",a,b)!=EOF)
{
memset(dp,63,sizeof(dp));
dp[0][0][0]=0;
int n=strlen(a);
for(int i=0;i<n;i++)
{
for(int j=0;j<10;j++)
{
for(int k=0;k<10;k++)
{
int tmp=((b[i]-a[i]-j)%10+10)%10;
for(int p=0;p<=tmp;p++)
{
for(int q=0;q<=p;q++)
{
dp[i+1][(k+p)%10][q]=min(dp[i+1][(k+p)%10][q],dp[i][j][k]+tmp);
}
}
tmp=10-tmp;
for(int p=0;p<=tmp;p++)
{
for(int q=0;q<=p;q++)
{
dp[i+1][((k-p)%10+10)%10][(10-q)%10]=min(dp[i+1][((k-p)%10+10)%10][(10-q)%10],dp[i][j][k]+tmp);
}
}
}
}
}
printf("%d\n",dp[n][0][0]);
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
}
return 0;
}
E题 图论题
从n-1到1枚举判断(建图判连通)是否能不选,输出选择的结果。做VJ时将队友的贪心卡了整场,快结果时我来写又写晕了.....
#include<cstdio>
#include<cmath>
#include<cstring>
int n,d;
int x[1111],y[1111];
int dis(int i,int j)
{
return ceil(sqrt(0.0+(x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j])));
}
char ans[1111];
int top;
bool vis[1111],use[1111];
int ev[111111],nxt[111111],head[1111],e;
void add(int u,int v)
{
//printf("%d %d\n",u,v);
ev[e]=v,nxt[e]=head[u];head[u]=e++;
}
void dfs(int u,int p)
{
vis[u]=1;
for(int i=head[u];~i;i=nxt[i])
{
int v=ev[i];
if(vis[v]) continue;
dfs(v,u);
}
}
int idx;
bool solve()
{
memset(vis,0,sizeof(vis));
dfs(0,0);
for(int i=1;i<n;i++) if(!vis[i]) return 0;
for(int i=n-1;i;i--)
{
use[i]=0;
memset(head,-1,sizeof(head));e=0;
for(int i=0;i<n;i++) for(int j=i+1;j<n;j++)
{
if(use[i]&&use[j]&&dis(i,j)<=d) add(i,j),add(j,i);
if(!use[i]&&!use[j]) continue;
if(!use[i]||!use[j]) if(dis(i,j)*2<=d) add(i,j),add(j,i);
}
memset(vis,0,sizeof(vis));
dfs(0,0);int need=0;
for(int j=0;j<n;j++) if(!vis[j]) need=1;
use[i]=need;
}
for(int i=n-1;~i;i--) ans[top++]=use[i]+48;
ans[top]=0;
idx=0;
while(ans[idx]==48) idx++;
return 1;
}
int main()
{
//freopen("in.txt","r",stdin);
while(scanf("%d%d",&n,&d)!=EOF)
{
e=top=0;
memset(use,1,sizeof(use));
memset(head,-1,sizeof(head));
use[0]=1;
for(int i=0;i<n;i++) scanf("%d%d",&x[i],&y[i]);
for(int i=0;i<n;i++) for(int j=i+1;j<n;j++) if(dis(i,j)<=d) add(i,j),add(j,i);
if(solve()) puts(ans+idx);
else puts("-1");
}
return 0;
}
H题 什么都不是的水题
#include<cstdio>
int t,x,y;
int main()
{
scanf("%d",&t);
while(t--)
{
double x,y,p,q;
scanf("%lf%lf%lf%lf",&x,&y,&p,&q);
double ans1=q*p*(x+y)+(1-q)*x;
double ans2=q*y+(1-q)*p*(x+y);
if(ans1>ans2) printf("tiger %.4lf\n",ans1);
else printf("wolf %.4lf\n",ans2);
}
return 0;
}