选举游戏
解题思路
不断寻找数组中的最大值,若最大值不是小东,则争取当前投票数最大的候选人1票,直到最大值为小东。这种方法耗时会比较久,但是对于n不是特别大的情况还是可以接受的。
以下代码是100%通过。
#include<iostream>
using namespace std;
int main(){
int n;
int a[105];
while(cin>>n){
int max=0;
int maxi=0;
for(int i=0;i<n;i++){
cin>>a[i];
if(max<=a[i]){
max=a[i];
maxi=i;
}
}
int ans=0;
while(maxi!=0){
a[0]++;
a[maxi]--;
ans++;
max=0;
maxi=0;
for(int i=0;i<n;i++)
if(max<=a[i]){
max=a[i];
maxi=i;
}
}
cout<<ans<<endl;
}
return 0;
}
三子棋
这个题目只过了60%,实在不知道没有考虑到哪里。
计算画叉的人的下棋数目x,画圈的人下棋数目o,空白的数目为d。
- 首先判断棋局是否不合法
给定棋局不合法的情况包括:
- o+d+x!=9
- x>o
- x-o>1
- 画叉赢,并且画圈也赢
- 然后判断是否有画叉或画圈的获胜
- 如果d=0,则为平局
- 最后判断下一轮先下棋的人
#include<iostream>
#include<stdio.h>
using namespace std;
char a[3][3];
bool valid(char c){
//cout<<1<<endl;
// 水平
for(int i=0;i<3;i++){
int j=0;
for(;j<3;j++)
if(a[i][j]!=c)break;
if(j==3)return true;
}
//cout<<2<<endl;
// 垂直
for(int i=0;i<3;i++){
int j=0;
for(;j<3;j++)
if(a[j][i]!=c)break;
if(j==3)return true;
}
//cout<<3<<endl;
// 对角
int i=0;
for(;i<3;i++)
if(a[i][i]!=c)break;
if(i==3)return true;
for(i=0;i<3;i++)
if(a[i][2-i]!=c)break;
if(i==3)return true;
return false;
}
int main(){
while(scanf("%s",a[0])!=EOF){
//getchar();
for(int i=1;i<=2;i++){
scanf("%*c%s",a[i]);
//getchar();
}
//for(int i=0;i<3;i++){
// for(int j=0;j<3;j++)
// cout<<a[i][j];
// cout<<endl;
//}
int x=0;
int o=0;
int d=0;
for(int i=0;i<3;i++){
for(int j=0;j<3;j++)
if(a[i][j]=='X')x++;
else
if(a[i][j]=='0')o++;
else
if(a[i][j]=='.')d++;
}
if((x+o+d)!=9||abs(x-o)>1||o>x){
cout<<"x"<<endl;
continue;
}
bool vx=valid('X');
bool vo=valid('0');
if(vx&&vo){
cout<<"x"<<endl;
continue;
}
if(vx){
cout<<"1 won"<<endl;
continue;
}
if(vo){
cout<<"2 won"<<endl;
continue;
}
if(d==0){
cout<<"draw"<<endl;
continue;
}
if(x==o){
cout<<"1"<<endl;
}else{
cout<<"2"<<endl;
}
}
}
在别人的题解里看到,棋局不合法还有一种情况:叉或圈存在多个赢的情况,以叉为例,存在直线两条以上或者存在一条水平一条垂直等情况。对以上代码的valid函数进行修改,使用一个变量flag记录赢的次数(让其获胜的情况,即记录几条水平、几条垂直、几条对角),对特殊棋局判断是否合法。valid返回为0,没有获胜;返回为1,对应的选手获胜;返回为-1,说明棋局不合法。
#include<iostream>
#include<stdio.h>
using namespace std;
char a[3][3];
int valid(char c){
// 水平
int flag=0;
for(int i=0;i<3;i++){
int j=0;
for(;j<3;j++)
if(a[i][j]!=c)break;
if(j==3)flag++;
}
// 垂直
for(int i=0;i<3;i++){
int j=0;
for(;j<3;j++)
if(a[j][i]!=c)break;
if(j==3)flag++;
}
// 对角
int i=0;
for(;i<3;i++)
if(a[i][i]!=c)break;
if(i==3)flag++;
for(i=0;i<3;i++)
if(a[i][2-i]!=c)break;
if(i==3)flag++;
if(flag==0||flag==1)return flag;
return -1;
}
int main(){
while(scanf("%s",a[0])!=EOF){
//getchar();
for(int i=1;i<=2;i++){
scanf("%*c%s",a[i]);
//getchar();
}
//for(int i=0;i<3;i++){
// for(int j=0;j<3;j++)
// cout<<a[i][j];
// cout<<endl;
//}
int x=0;
int o=0;
int d=0;
for(int i=0;i<3;i++){
for(int j=0;j<3;j++)
if(a[i][j]=='X')x++;
else
if(a[i][j]=='0')o++;
else
if(a[i][j]=='.')d++;
}
if((x+o+d)!=9||abs(x-o)>1||o>x){
cout<<"x"<<endl;
continue;
}
int vx=valid('X');
int vo=valid('0');
if(vx==-1||vo==-1||vx&&vo){
cout<<"x"<<endl;
continue;
}
if(vx){
cout<<"1 won"<<endl;
continue;
}
if(vo){
cout<<"2 won"<<endl;
continue;
}
if(d==0){
cout<<"draw"<<endl;
continue;
}
if(x==o){
cout<<"1"<<endl;
}else{
cout<<"2"<<endl;
}
}
}
本文介绍了两道算法题的解决方案:一是通过不断调整投票数使特定候选人获胜的选举游戏;二是针对三子棋游戏状态判断合法性及胜负情况的实现方法。代码示例采用C++语言。
1236

被折叠的 条评论
为什么被折叠?



