A - Combination Lock
题意:
给两个密码,为最小多少次能吻合。
思路:
对于每一位设a<b,sum+=min(b-a,10+a-b)
#include <bits/stdc++.h>
using namespace std;
int main()
{
int n;
char x[1234],y[1234];
while(cin>>n)
{
scanf("%s%s",x,y);
int ans=0;
for(int i=0;i<n;i++)
{
int a=x[i]-'0';
int b=y[i]-'0';
if(a>b) swap (a,b);
ans+=min(b-a,10+a-b);
}
printf("%d\n",ans);
}
return 0;
}
B - School Marks
题意:
给n,k,p,x,y,代表总共有n个数,已知有k个数,这些数的最大值不能超过p,数的总和不能超过x,排序完的中位数大于等于y
问剩下的n-k个数是什么,输出任意答案。
思路:
先统计k个数中小于y的数有cnt个,cnt不能大于n/2,顺便求和。
接着放n/2-cnt个1,这里要注意有可能中位数就是1,那么顺便计算一下放了多少个数,放满n个了也要停。
接着剩下的放y,判断和是否会超过。
代码:
#include <bits/stdc++.h>
using namespace std;
int v[1234];
int main()
{
int n,k,p,x,y;
while(cin>>n>>k>>p>>x>>y)
{
int sum=0,cnt=0,kx=0;
for(int i=0;i<k;i++)
{
int x;
scanf("%d",&x);
if(x<y) cnt++;
sum+=x;
}
if(cnt>n/2)
{
puts("-1");
continue;
}
for(int i=cnt;i<n/2 && k<n;i++) //k<n 防止中位数正好是1
{
k++;
sum++;
v[kx++]=1;
}
for(int i=k;i<n;i++)
{
sum+=y;
v[kx++]=y;
}
if(sum>x) printf("-1\n");
else for(int i=0;i<kx;i++) printf(i==kx-1?"%d\n":"%d ",v[i]);
}
return 0;
}
C - Ice Cave
题意:
给n*m的矩阵有‘.’和'X',点代表冰面,X代表洞。冰面走过后就变成洞。
然后给起点和终点,问能否从起点走到终点,正好掉进终点的洞里,除了终点的洞其他洞不能再走。
思路:
很考验脑洞的一道题,因为判断可达,所以可以直接dfs判断,比bfs来的快并且简单。
只要考虑一个点是否被走了2次就好了,根据dfs的特性直接就是答案了。
代码:
#include <bits/stdc++.h>
using namespace std;
int v[1234];
char mp[555][555];
int used[555][555];
int dis[4][2]= {{0,1},{0,-1},{-1,0},{1,0}};
int f,sx,sy,ex,ey,n,m;
void dfs(int x,int y)
{
if(f) return;
if(x<0 || x>=n || y<0 || y>=m ) return ;
if(x==ex && y==ey && used[x][y]>=2)
{
f=1;
return ;
}
if(used[x][y]>=2) return ;
used[x][y]++;
for(int i=0; i<4; i++)
{
int xx=x+dis[i][0];
int yy=y+dis[i][1];
dfs(xx,yy);
if(f) return;
}
}
int main()
{
while(scanf("%d%d",&n,&m)!=-1)
{
for(int i=0; i<n; i++)
{
scanf("%s",mp[i]);
for(int j=0; j<m; j++)
{
if(mp[i][j]=='.') used[i][j]=1;
else used[i][j]=2;
}
}
cin>>sx>>sy>>ex>>ey;
sx--;
sy--;
ex--;
ey--;
f=0;
used[sx][sy]=1;
dfs(sx,sy);
puts(f==1?"YES":"NO");
}
return 0;
}
D - Bad Luck Island
题意:
一个岛上有3个物种石头、剪刀、布,各a、b、c个。
每次随机两个东西碰面,相克的话被克的死掉,否则平安无事。
分别求三个物种只有这个物种剩下来的概率。
思路:
一个概率dp,设dp[i][j][k]为当前有i个石头,j个剪刀,k个布,石头留下的概率。
那么对于每个状态来说,都只会发生两种事情,就是某个物种少1或者大家平安。
所以 dp[i][j][k]=(i*j)/(sum*(sum-1)/2)*dp[i][j-1][k]+(j*k)/(sum*(sum-1)/2)
*dp[i][j][k-1]+(k*i)/(sum*(sum-1)/2)*dp[i-1][j][k]+(C(i,2)+C(j,2)+C(k,2))/(sum*(sum-1)/2)*dp[i][j][k]
然后移项求解一下就好了。
用的是记忆化搜索,然后考虑一下边界就好了。
对于石头赢的话就是。
if(!i) return 0.0;
if(!j) return 1.0;
if(!k) return 0.0;
然后因为太弱了,所以算三遍分别求出每个种类赢的概率。
代码:
#include <bits/stdc++.h>
#define eps 1e-10
using namespace std;
double dp1[101][101][101];
double dfs1(int a,int b,int c) //石头
{
if(!a) return 0.0;
if(!c) return 1.0;
if(!b) return 0.0;
if(fabs(dp1[a][b][c]+1)>eps) return dp1[a][b][c];
double ans=0.0;
double cnt=a+b+c;
cnt=(cnt*(cnt-1.0))/2;
double bs=0.0;
if(a>=2) bs+=(1.0*a*(a-1.0))/2;
if(b>=2) bs+=(1.0*b*(b-1.0))/2;
if(c>=2) bs+=(1.0*c*(c-1.0))/2;
bs=bs/cnt;
bs=1.0-bs;
ans+=(a*c)/cnt*dfs1(a-1,b,c);
ans+=(c*b)/cnt*dfs1(a,b,c-1);
ans+=(b*a)/cnt*dfs1(a,b-1,c);
ans=ans/bs;
return dp1[a][b][c]=ans;
}
double dp2[101][101][101];
double dfs2(int a,int b,int c) //剪刀
{
if(!b) return 0.0;
if(!a) return 1.0;
if(!c) return 0.0;
if(fabs(dp2[a][b][c]+1)>eps) return dp2[a][b][c];
double ans=0.0;
double cnt=a+b+c;
cnt=(cnt*(cnt-1.0))/2;
double bs=0.0;
if(a>=2) bs+=(1.0*a*(a-1.0))/2;
if(b>=2) bs+=(1.0*b*(b-1.0))/2;
if(c>=2) bs+=(1.0*c*(c-1.0))/2;
bs=bs/cnt;
bs=1.0-bs;
ans+=(a*c)/cnt*dfs2(a-1,b,c);
ans+=(c*b)/cnt*dfs2(a,b,c-1);
ans+=(b*a)/cnt*dfs2(a,b-1,c);
ans=ans/bs;
return dp2[a][b][c]=ans;
}
double dp3[101][101][101];
double dfs3(int a,int b,int c) //布
{
if(!c) return 0.0;
if(!b) return 1.0;
if(!a) return 0.0;
if(fabs(dp3[a][b][c]+1)>eps) return dp3[a][b][c];
double ans=0.0;
double cnt=a+b+c;
cnt=(cnt*(cnt-1.0))/2;
double bs=0.0;
if(a>=2) bs+=(1.0*a*(a-1.0))/2;
if(b>=2) bs+=(1.0*b*(b-1.0))/2;
if(c>=2) bs+=(1.0*c*(c-1.0))/2;
bs=bs/cnt;
bs=1.0-bs;
ans+=(a*c)/cnt*dfs3(a-1,b,c);
ans+=(c*b)/cnt*dfs3(a,b,c-1);
ans+=(b*a)/cnt*dfs3(a,b-1,c);
ans=ans/bs;
return dp3[a][b][c]=ans;
}
int main()
{
int a,b,c;
memset(dp1,-1,sizeof(dp1));
memset(dp2,-1,sizeof(dp2));
memset(dp3,-1,sizeof(dp3));
while(cin>>a>>b>>c)
{
printf("%.10f %.10f %.10f\n",dfs1(a,b,c),dfs2(a,b,c),dfs3(a,b,c));
}
return 0;
}