A 做游戏
牛牛和 牛可乐在玩石头剪刀布。
众所周知,石头剪刀布的规则是这样的:
- 在一局游戏中,双方各自出石头、剪刀、布其一。
- 胜负关系如下:
牛牛和 牛可乐进行了多轮游戏, 牛牛总共出了 A 次石头,B 次剪刀,C 次布;牛可乐总共出了 X 次石头,Y 次剪刀,Z 次布。 你需要求出 牛牛最多获胜多少局。
输入描述:
第一行,三个非负整数 A,B,C 。
第二行,三个非负整数 X,Y,Z 。
保证 A+B+C=X+Y+Z, 0<= A,B,C,X,Y,Z<= 10^9A+B+C=X+Y+Z,0≤A,B,C,X,Y,Z≤10
9
。
输出描述:
输出一行,一个整数表示答案。
示例1
输入
复制
114514 0 0
0 114514 0
输出
复制
114514
思路:要求妞妞最多胜了多少局,只需要在必赢的局数上面取min,比如min(石头,剪刀),这就是石头最多能够赢的局数,同理min(剪刀,布),min(布,石头),因为题目保证了A+B+C=X+Y+Z,剩下来多余的剪刀石头布为使赢的局数最大总能打平局。
代码:
#include<iostream>
using namespace std;
typedef long long int ll;
int main(){
ll A,B,C,X,Y,Z;
cin>>A>>B>>C>>X>>Y>>Z;
ll ans=min(A,Y)+min(B,Z)+min(C,X);
cout<<ans<<endl;
}
G 判正误
思路:题目简单易懂只需要判 a ^ d + b ^ e + c ^ f == g 就行了,不过math.h提供的pow时间复杂度O(n)用快速幂可以达到O(log),因为10910^9 可能暴long long 了,所以玄学mod 1e9 + 7
代码:
#include<iostream>
using namespace std;
const int mod = 1e9 + 7;
typedef long long int ll;
ll a,b,c,d,e,f,g;
ll _pow(ll a,ll n){
ll ans=1;
while(n){
if(n&1)ans=(ans*a)%mod;
a=(a*a)%mod;
n>>=1;;
}
return ans;
}
int main(){
int T;cin>>T;
while(T--){
cin>>a>>b>>c>>d>>e>>f>>g;
ll x=_pow(a,d);
ll y=_pow(b,e);
ll z=_pow(c,f);
if(g == x+y+z){
cout<<"Yes"<<endl;
}else{
cout<<"No"<<endl;
}
}
}
B 排数字
思路:先注意到 61616是可以组成两个的,中间的重复用了一次,因为可以任意排,所以只需要统计6的个数和1的个数,然后分类处理。当6的个数>1的个数 ,答案是1的个数,当6的个数等于1的个数答案是1的个数-1,当6的个数<1的个数答案是6的个数-1
代码:
#include<iostream>
#include<string>
using namespace std;
int six,one;
int main(){
int n;scanf("%d",&n);
for(int i=0;i<n;i++){
char x;scanf(" %c",&x);
if(x=='6')six++;
if(x=='1')one++;
}
if(six>one)
cout<<one<<endl;
else if(six==one)
cout<<one-1<<endl;
else cout<<six-1<<endl;
}
D 数三角
思路:O(n^3)枚举每个三角形,求出每个三角形的三条边,满足最大边的平方>较小边的平方和一定是钝角,并且需要把共线的平角特殊判掉。
代码:
#include<iostream>
#include<math.h>
using namespace std;
const int maxn = 1e3+10;
struct point{
int x,y;
point(){}
point(int a,int b):x(a),y(b){}
}ans[maxn];
long long distance(int x1,int y1,int x2,int y2){
return (long long)((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
}
int main(){
int n;cin>>n;
int res=0;
for(int i=0;i<n;i++)scanf("%d%d",&ans[i].x,&ans[i].y);
for(int i=0;i<n;i++){
for(int j=i+1;j<n;j++){
for(int k=j+1;k<n;k++){
long long a=distance(ans[i].x,ans[i].y,ans[j].x,ans[j].y);
long long b=distance(ans[j].x,ans[j].y,ans[k].x,ans[k].y);
long long c=distance(ans[i].x,ans[i].y,ans[k].x,ans[k].y);
bool flag = ((ans[k].y-ans[i].y)*(ans[j].x-ans[i].x)-(ans[j].y-ans[i].y)*(ans[k].x-ans[i].x))==0;
long long m=max(a,max(b,c));
if(m == a&&b + c < a&&!flag)res++;
if(m == b&&a + c < b&&!flag)res++;
if(m == c&&a + b < c&&!flag)res++;
}
}
}
cout<<res<<endl;
}
F 拿物品
思路:为了使得H和T属性和越大,每次选择最大的属性总是好的,当牛牛选择ai属性,意味着可乐牛将损失bi属性,换言之就是牛牛得到ai+bi属性,为使得属性和最大,需要一次降序排序,在依次选取即可。
代码:
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn = 1e5*2 + 10;
struct node{
long long int v;
int ind;
}a[maxn];
bool cmp(node a,node b){
return a.v>b.v;
}
int main(){
int n;cin>>n;
for(int i=0;i<n;i++)cin>>a[i].v;
for(int i=0;i<n;i++){
long long int x;cin>>x;
a[i].v+=x;
a[i].ind=i;
}
sort(a,a+n,cmp);
for(int i=0;i<n;i++){
if(!(i&1))cout<<1+a[i].ind<<" ";
}
cout<<endl;
for(int i=0;i<n;i++){
if(i&1)cout<<1+a[i].ind<<" ";
}
}
E 做计数
思路:
根号i + 根号j = 根号k (两边同时平方)
i + j +根号 i * j = k
因为k是一个整数,所以等式存在的冲要条件是 i *j 是完全平方数
有i *j <=n,所以我们只需要枚举[1,n]的完全平方数,并且求出他们的因子个数就是答案了。
代码:
#include<iostream>
using namespace std;
typedef long long int ll;
ll n;
int main(){
cin>>n;
int ans=0;
for(int i=1;i*i<=n;i++){
for(int j=1;j<=i;j++){
if((i*i)%j==0)ans+=2;
if(j*j == i*i)ans-=1;
}
}
cout<<ans<<endl;
}
C 算概率
思路:
dp[i][j]:表示前i道题正确j道题目的概率
转移方程:dp[i][j] = dp[i-1][j]*(1-p[i])+p[i]*dp[i-1][j-1]
动态规划太过巧妙。
代码:
#include<iostream>
using namespace std;
typedef long long int ll;
const int mod = 1e9 + 7;
const int maxn = 1e3*2 + 10;
ll dp[maxn][maxn],p[maxn];
/* dp[i][j]:表示前i道题正确j道题目的概率 转移方程:dp[i][j] = dp[i-1][j]*(1-p[i])+p[i]*dp[i-1][j-1] */
int main(){
ll n;cin>>n;
dp[0][0]=1;
for(int i=1;i<=n;i++)cin>>p[i];
for(int i=1;i<=n;i++){
dp[i][0] = dp[i-1][0]*(mod+1-p[i])%mod;
for(int j=1;j<=i;j++){
dp[i][j] = (dp[i-1][j]*(mod+1-p[i]) + (p[i])*(dp[i-1][j-1]))%mod;
}
}
for(int i=0;i<=n;i++)
cout<<dp[n][i]<<" ";
}