首页 > 试题广场 >

关灯游戏

[编程题]关灯游戏
  • 热度指数:1487 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/C++ 64M,其他语言128M
  • 算法知识视频讲解
在 Alice 生日的那天, Bob 送给了她 n 个灯泡。他们决定用这些灯泡玩一个游戏:他们把这些灯泡从左往右排成一行,在初始时,有些灯泡是点亮的,有些灯泡是熄灭的。接下来,他们轮流进行操作,Alice 首先操作。在每一次操作中,轮到操作的人需要选择一个点亮的灯泡,然后把它以及它右边的所有灯泡的状态进行一次改变,即把点亮的灯泡熄灭,把熄灭的灯泡点亮。如果在某一个人操作完之后,所有的灯泡都变成了熄灭状态,那么那个人就赢得了游戏。 Alice 和 Bob 都想赢得游戏,在他们都足够聪明的情况下,最后谁会赢呢?

数据范围: , 输入只包含 0 和 1

输入描述:
第一行包含一个整数 ,表示灯泡的个数。

第二行包含 个 0 或 1,表示初始时灯泡的状态,0 表示熄灭,1 表示点亮。



输出描述:
如果最后Alice能赢,输出Alice,或则输出Bob。
示例1

输入

3
0 1 1

输出

Alice
示例2

输入

5
1 1 1 0 0

输出

Bob
#include <bits/stdc++.h>
using namespace std;
int main()
{
    int n;     
    while(cin>>n)     
    {         
        int a[n];         
        for(int i=0;i<n;i++)             
            cin>>a[i];         
        if(a[n-1])             
            puts("Alice");         
        else             
            puts("Bob");     
    }     
    return 0;
}

发表于 2019-06-26 20:29:35 回复(0)
if __name__ == "__main__": 
    line = raw_input()
    n = int(line)
    line = raw_input()
    lines = line.split()
    a = [int(item) for item in lines]
    dp = [0 for i in range(n)]
    dp[n-1] = a[n-1]
    count  = 0
    for i in range(n-2,-1,-1):
        if a[i] == 1:
            dp[i] = 2+dp[i+1]
        else:
            dp[i] = dp[i+1]    
    if dp[0]%2 == 1:
        print "Alice"
    else:
        print "Bob"
一个动态规划,即可求解,从尾部向头部逐步规划。
发表于 2019-05-15 09:29:33 回复(0)
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

/**
 * @author wylu
 */
public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        br.readLine();
        String[] strs = br.readLine().split(" ");
        System.out.println(strs[strs.length - 1].equals("1") ? "Alice" : "Bob");
    }
}

发表于 2019-03-14 14:56:01 回复(0)
#include <bits/stdc++.h>

using namespace std;

int main()
{     int n;     while(cin>>n)     {         int a[n];         for(int i=0;i<n;i++)             cin>>a[i];         if(a[n-1])             puts("Alice");         else             puts("Bob");     }     return 0;
}

发表于 2019-01-26 02:07:34 回复(1)
n=int(input())
arr=list(map(int,input().split(" ")))
"""
最后一个灯为0,为了将所有灯熄灭,必操作偶数次,则Bob必胜;
最后一个灯为0,为了将所有灯熄灭,必操作奇数次,则Alice必胜;
"""
if arr[-1]==0:
    print("Bob")
else:
    print("Alice")

发表于 2019-04-28 13:10:36 回复(2)
#include<iostream>
using namespace std;
int main(){
    int n,change=0;
    cin>>n;
    int x[n];
    for(int i=1;i<=n;i++){
        cin>>x[i];
        if(x[i]!=x[i-1])
            change++;         //计算变化次数
    }
    if(x[0]==0){              //根据第一个为0或者1以及变化次数进行讨论
        if(change%2==0)
            cout<<"Bob"<<endl;
        else
            cout<<"Alice"<<endl;
    }
    if(x[0]==1){
        if(change%2==0)
            cout<<"Alice"<<endl;
        else
            cout<<"Bob"<<endl;
        
    }
}
影响获胜者的只有两点:01的交替次数以及第一个是0还是1
用的老实人方法写的,比较好理解
发表于 2019-09-21 17:45:34 回复(0)
import java.util.Scanner;
public class Main{
    public String game(int n,int[] light){
        int turnNum=0;   //换灯泡次数
        //关灯游戏可理解为,将相邻连续的几盏状态相同的灯视为同一盏(因为进行操作时状态同步变化)
        //如存在10盏灯:0 0 1 0 0 1 1 1 0 1  ,合并连续的相同状态的灯后,可视为:0 1 0 1 0 1
        //再去掉最左边已熄灭的灯,可视为:1 0 1 0 1,剩余数字数量为5,则需要进行5次操作可赢得游戏
        int val=0;       
        for(int i=0;i<n;i++) {
        	if(light[i]!=val) {
        		turnNum++;
        		val=light[i];
        	}
        }
        if(turnNum%2==1) {
        	return "Alice";  //换奇数次为Alice赢
        }
        else {
        	return "Bob";   //**数次为Bob赢
        }
    }
    //main方法
    public static void main(String[] args){
        Scanner sc=new Scanner(System.in);
        int n=sc.nextInt();  // n为灯泡数量
        int[] a=new int[n];  //根据灯泡数量创建对应长度的数组,如 5
        for(int i=0;i<n;i++){ //循环将键盘输入的整数存入数组,如 1 0 0 1 1
            a[i]=sc.nextInt();
        }
        System.out.println(new Main().game(n,a));
    }
}

编辑于 2020-09-10 04:14:55 回复(0)
#include<stdio.h>
int main()
{
    int n = 0;
    int x = 0;
    scanf("%d",&n);
    while(n--)
    {
        scanf("%d",&x);
    }
    if(x)
    {
        printf("Alice\n");
    }
    else
    {
        printf("Bob\n");
    }
    return 0;
}


发表于 2019-05-01 21:17:38 回复(0)
#include<iostream>
using namespace std;
int main()
{
    int n,arr[100001];
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        cin>>arr[i];
    }
    if(arr[n])
        cout<<"Alice"<<endl;
    else
        cout<<"Bob"<<endl;
}
根据最后一次输入数值是否为1进行判断:
1、当序列分布为000011111类型,即最后一位的1与前面为1的数值是相连的,则只进行一次操作即可;
2、当最后一位的1与前面为1的数值是间隔的,则将数值变为000011111类型需要经过偶数次操作,然后再进行一次操作达到要求。
发表于 2019-04-20 11:32:46 回复(0)
#include<iostream>
#include<stdio.h>
#include<string>
using namespace std;
int main()
{
    int n;
    cin >> n;
    getchar();//复习
    string line;
    getline(cin,line);
    cout << ((line[line.size()-1] == '1')? "Alice" : "Bob");
    // 解析:
    // 每次操作相当于由0、1组成的2进制数减1,每个回合减2,奇数时A胜,偶数时B胜
    return 0;
}

发表于 2019-04-09 21:03:59 回复(0)
最后一个是1,一定是Alice赢
最后一个是0,一定是Bob赢
#include<stdio.h>
int main()
{
    int n;
    scanf("%d",&n);
    int a[n];
    for(int i=0;i<n;i++)
    {
        scanf("%d",&a[i]);
    }
    if(a[n-1]) printf("Alice");
    else printf("Bob");
    return 0;
}

发表于 2019-01-26 12:23:05 回复(2)