Algorithm 同余偶和对策

Algorithm 同余偶和对策,algorithm,Algorithm,我正在努力完成Codibility挑战,以提高我的编程技能。挑战的细节如下。 我也会把问题陈述抄下来 偶数和是两个人的游戏。给玩家一个N的序列 正整数和整数交替使用。在每一回合中,一名球员 选择非空切片(连续元素的子序列),如 如果此切片中的值之和为偶数,则删除该切片 并连接序列的其余部分。第一名选手 无法采取合法行动的人将输掉比赛 你和你的对手玩这个游戏,你想知道你是否 如果你和你的对手都打得很好,你就能赢。你动 首先 编写一个函数: 字符串解决方案(向量&A) 给定由N个整数组成的零索引数

我正在努力完成Codibility挑战,以提高我的编程技能。挑战的细节如下。
我也会把问题陈述抄下来

偶数和是两个人的游戏。给玩家一个N的序列 正整数和整数交替使用。在每一回合中,一名球员 选择非空切片(连续元素的子序列),如 如果此切片中的值之和为偶数,则删除该切片 并连接序列的其余部分。第一名选手 无法采取合法行动的人将输掉比赛

你和你的对手玩这个游戏,你想知道你是否 如果你和你的对手都打得很好,你就能赢。你动 首先

编写一个函数:

字符串解决方案(向量&A)

给定由N个整数组成的零索引数组a,返回 格式为“X,Y”的字符串,其中X和Y分别是第一个和第二个 应在计算机上删除的切片的最后位置(包括) 假设你有一个获胜的策略,那么你首先要做的就是获胜。如果 如果有多个这样的获胜片段,则函数应返回 最小值为X的一个。如果有多个切片 如果X的值最小,则函数应返回最短值。 如果没有获胜策略,函数应返回“否” 解决办法”

例如,给定以下数组:

A[0]=4A[1]=5A[2]=3A[3]=7A[4]=2函数 应返回“1,2”。从位置1到2移除切片后 (偶数和为5+3=8),剩下的数组是[4,7,2]。 然后对手将能够移除第一个元素(偶数) 和4)或最后一个元素(偶数和2)。然后你可以做一个 使阵法只包含[7]的移动,因此你的对手将 没有合法的行动,将会失败。其中一个可能的游戏显示在 下图:

请注意,删除切片“2,3”(偶数和为3+7=10)是非常困难的 这也是一个成功的动作,但是切片“1,2”的值X较小

对于以下阵列:

A[0]=2A[1]=5A[2]=4函数应返回“否 “解决方案”,因为没有任何策略可以保证您获胜

假设:

N是[1..100000]范围内的整数;数组的每个元素 是范围[1..100000000]内的整数。复杂性:

期望最坏情况时间复杂度为O(N);期望最坏情况空间 复杂性为O(N),超出输入存储(不计算存储 输入参数是必需的)。输入数组的元素可以是 修改

首先,我对问题陈述有一个误解,为什么在给定的示例中,第一个玩家在第一步中不能将4作为偶数范围,所以函数应该返回0,0而不是1,2


第二个解决问题的想法是计算输入数组中的偶数范围,如果计数是偶数,那么玩家一赢,我应该找到玩家一可以占据的第一个偶数范围

但是我不能在分配的时间内解决它,也不能再参加考试

以下是我的尝试代码:

    string solution(vector<int> &A) {
    int num_even_ranges = 0;
    int sum = 0;
    for (int i = 0; i < A.size(); i++)
    {
        sum += (A[i]%2);
        if (sum % 2 == 0 || A[i]%2 == 0)
        {
            num_even_ranges++;
            sum = 0;
        }
    }
    if (num_even_ranges % 2 == 0)
        return "NO SOLUTION";
    sum = 0;
    int start = 0;
    for (int i = start; i < A.size(); i++)
    {
        sum += A[i];
        if (sum % 2 == 0 && i > start)
        {
            return to_string(start) + "," + to_string(i);
        }

        if (i + 1 < A.size())
        {
            if (A[i] % 2 == 0 && A[i+1] % 2 == 1)
            {
                sum = 0;
                start = i + 1;
            }
        }
    }
}
字符串解决方案(向量&A){
int num_偶数_范围=0;
整数和=0;
对于(int i=0;istart)
{
返回到_字符串(开始)+“,“+到_字符串(i);
}
如果(i+1


我对这个问题的解决方案是正确的吗?如果不是,那么这个有趣的问题的正确解决方案是什么。

关于你的第一个问题,如果第一个玩家取4(0,0),剩余的数组是:5,3,7,2。然后对手可以拿下3,7,2,第一个玩家将被释放,因为剩下的5个是奇数。所以这不是有效的解决方案。

移动(0,0)是有效的,因为在每一回合中,玩家只能使用和为偶数的子序列进行移动

“在每一回合中,玩家选择一个非空的分片(一个分片的子序列) 连续元素),以便此切片中的值之和为 甚至”

注:每次移动后,我们只考虑剩余序列

的操作/移动。
After player1's first move(0,0), the remaining sequence will be [5,3,7,2],
then player2's first move(0,1), the remaining sequence will be [7,2],
then player1's second move(1,0), the remaining sequence will be [7]
Now player 2 is unable to make any legal move! So player 1 win's 

因此,这是一个成功的策略

我得到了Javascript的解决方案,请参考下面的代码

Javascript代码:

function len(obj){
if(obj instanceof Array || typeof obj === "string")
    return obj.length;
else {
    var count = 0;
    for(var i in obj){
        if(obj.hasOwnProperty(i))
        count++;
    }
    return count;
}
}

function check(start, end) {
if (start > end) {
    res = 'NO SOLUTION';
}
else {
    res = start.toString() + ',' + end.toString();
}

return res;
}

function trans(strr){
if (strr =='NO SOLUTION') {
    return [1, -1]
}
else {
   a = strr.split(',');
}

return [parseInt(a[0]), parseInt(a[1])];
}

function solution(A){
odd_list = [];
for(var ind=0; ind<A.length; ind++)
{
    if(A[ind]%2==1) {
        odd_list.push(parseInt(ind));    
    }
}

if (len(odd_list)%2 == 0) {
    return check(0, len(A) - 1);
}

 tempList = odd_list;
 odd_list = [];

 odd_list.push(-1);

 for(var i=0; i< tempList.length; i++) {
     odd_list.push(tempList[i]);
 }

 odd_list.push(len(A));

 var res_cand = [];
 count = odd_list[1];
 second_count = len(A) - 1 - odd_list[odd_list.length-2];
 first_count = odd_list[2]- odd_list[1] - 1;

 if (second_count >= count) {
    res_cand.push(trans(check(odd_list[1] + 1 , len(A) - 1 - count ))); 
 }

 if (first_count >= count) {
    res_cand.push(trans(check(odd_list[1] + count + 1, len(A) - 1))) 
 }

twosum = first_count + second_count;

if (second_count < count && count <= twosum) {
    res_cand.push(trans(check(odd_list[1] + (first_count - (count -     second_count )) + 1, odd_list[odd_list.length-2] )));
}

count = len(A) - 1 - odd_list[odd_list.length-2];
first_count = odd_list[1];
second_count = odd_list[odd_list.length-2] - odd_list[odd_list.length-3] - 1;

if(first_count >= count) {
    res_cand.push(trans(check( count, odd_list[odd_list.length-2] - 1 )));
}

if (second_count >= count) {
    res_cand.push(trans(check( 0, odd_list[odd_list.length-2] - count - 1)))
}

twosum = first_count + second_count;

if(second_count < count && count <= twosum) {
    res_cand.push(trans(check(count-second_count, odd_list[odd_list.length-3])))
}

cur = [-1, -2];

res_cand =  res_cand.sort(sortFunction);

for(var i= res_cand.length-1 ; i >= 0 ; i--) {
      var row = res_cand[i]; 
      if(row[0] !== -1) {
        cur = row;  
      }
}

return check(cur[0], cur[1]);
}

function sortFunction(a, b) {
if (a[0] === b[0]) {
    return 0;
}
else {
    return (a[0] < b[0]) ? -1 : 1;
}
}
功能透镜(obj){
if(数组的obj实例| | obj的类型==“字符串”)
返回对象长度;
否则{
var计数=0;
用于(obj中的var i){
if(对象为自有财产(i))
计数++;
}
返回计数;
}
}
功能检查(开始、结束){
如果(开始>结束){
res=‘无解’;
}
否则{
res=start.toString()+','+end.toString();
}
返回res;
}
功能转换(strr){
如果(strr==‘无解决方案’){
返回[1,-1]
}
否则{
a=strr.split(',');
}
返回[parseInt(a[0]),parseInt(a[1]);
}
函数解(A){
奇数列表=[];

对于(var ind=0;ind

我同意玩家在任何情况下都必须获胜。