GG and MM


终于不是SG函数了,这个是  Every_SG博弈  ;其实是SG 的变形。。。。。。

题目有N个游戏同时进行,每个游戏有两堆石子,每次从个数多的堆中取走数量小的数量的整数倍的石子。取最后一次的获胜。

结论出自一篇论文吧:  必胜当且仅当所有的单一游戏步数最大的为奇数!!!

所以我们考虑步数就行了,当A/B==1  就没什么好说的了,就是单纯的取走B.

当A/B>=2  时:  听说就具有优先权,可以控制。将所有的X/Y>=2控制在自己手中,到了最后一个,便可以控制奇偶,让自己获胜。以此得到最大的步数,判断奇偶


代码中有一段确实不太懂,路过的大牛知道可以详细讲一下的微笑


#include<cstdio>
#include<iostream>
using namespace std;


int sg[110];
int main()
{
    int n,x,a,b,l;
    while(scanf("%d",&n)!=EOF)
    {
        int ans=0;
        for(int K=0;K<n;K++)
        {
            scanf("%d%d",&a,&b);
            if(a<b)  swap(a,b);
            sg[1]=a;sg[2]=b;l=2;
            while(sg[l])
            {
                sg[l+1]=sg[l-1]%sg[l];
                l++;
            }
            int cnt=-1,i;
            for(i=1,x=l-2;i<=l-2;i++)
            {
                if(sg[i]/sg[i+1]>1)
                {
                    if(cnt>0&&i%2!=cnt%2)   x++;//  就是这个I%2!=cnt%2???
                    cnt=i;
                }
            }
            ans=max(ans,x);
        }
       if(ans&1)  puts("MM");
       else puts("GG");
    }
    return 0;

}




#include <stdio.h> #include <conio.h> #include <stdlib.h> #include <time.h> #include <string.h> #define MM 8 /* RS code over GF(2**MM) */ #define KK 239 /* KK = number of information symbols */ #define NN ((1 << MM) - 1) #define TT 8 /* Error correction capability */ #define DEBUG 0 /* Disable debug output by default */ #if (MM < 8) typedef unsigned char dtype; #else typedef unsigned int dtype; #endif #if (KK >= NN) #error "KK must be less than 2**MM - 1" #endif /* Primitive polynomials */ #if(MM == 2) int pp[MM + 1] = { 1, 1, 1 }; #elif(MM == 3) int pp[MM + 1] = { 1, 1, 0, 1 }; #elif(MM == 4) int pp[MM + 1] = { 1, 1, 0, 0, 1 }; #elif(MM == 5) int pp[MM + 1] = { 1, 0, 1, 0, 0, 1 }; #elif(MM == 6) int pp[MM + 1] = { 1, 1, 极0, 0, 0, 0, 1 }; #elif(MM == 7) int pp[MM + 1] = { 1, 0, 0, 1, 0, 0, 0, 1 }; #elif(MM == 8) int pp[MM + 1] = { 1, 0, 1, 1, 1, 0, 0, 0, 1 }; #elif(MM == 9) int pp[MM + 1] = { 1, 0, 0, 0, 1, 0, 0, 0, 0, 1 }; #elif(MM == 10) int pp[MM + 1] = { 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1 }; #elif(MM == 11) int pp[MM + 1] = { 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1 }; #elif(MM == 12) int pp[MM + 1] = { 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1 }; #elif(MM == 13) int pp[MM + 1] = { 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1 }; #elif(MM == 14) int pp[MM + 1] = { 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1 }; #elif(MM == 15) int pp[MM + 1] = { 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }; #elif(MM == 16) int pp[MM + 1] = { 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1 }; #else #error "MM must be in range 2-16" #endif int alpha_to[NN + 1]; int index_of[NN + 1]; int gg[NN - KK + 1]; int recd[NN]; int err_flag; dtype data[KK], bb[NN - KK]; void generate_gf() { register int i, mask; mask = 1; alpha_to[MM] = 0; for (i = 0; i < MM; i++) { alpha_to[i] = mask; index_of[alpha_to[i]] = i; if (pp[i] != 0) alpha_to[MM] ^= mask; mask <<= 1; } index_of[alpha_to[MM]] = MM; mask >>= 1; for (i = MM + 1; i < NN; i++) { if (alpha_to[i - 1] >= mask) alpha_to[i] = alpha_to[MM] ^ ((alpha_to[i - 1] ^ mask) << 1); else alpha_to[i] = alpha_to[i - 1] << 1; index_of[alpha_to[i]] = i; } index_of[0] = -1; } void gen_poly() { register int i, j; gg[0] = 2; /* primitive element alpha = 2 */ gg[1] = 1; /* g(x) = (X+alpha) initially */ for (i = 2; i <= NN - KK; i++) { gg[i] = 1; for (j = i - 1; j > 0; j--) if (gg[j] != 0) gg[j] = gg[j - 1] ^ alpha_to[(index_of[gg[j]] + i) % NN]; else gg[j] = gg[j - 1]; gg[0] = alpha_to[(index_of[gg[0]] + i) % NN]; } /* convert gg[] to index form */ for (i = 0; i <= NN - KK; i++) gg[i] = index_of[gg[i]]; } void encode_rs() { register int i, j; int feedback; for (i = 0; i < NN - KK; i++) bb[i] = 0; for (i = KK - 1; i >= 极0; i--) { feedback = index_of[data[i] ^ bb[NN - KK - 1]]; if (feedback != -1) { for (j = NN - KK - 1; j > 0; j--) if (gg[j] != -1) bb[j] = bb[j - 1] ^ alpha_to[(gg[j] + feedback) % NN]; else bb[j] = bb[j - 1]; bb[0] = alpha_to[(gg[0] + feedback) % NN]; } else { for (j = NN - KK - 1; j > 0; j--) bb[j] = bb[j - 1]; bb[0] = 0; } } } void decode_rs() { register int i, j, u, q; int elp[NN - KK + 2][NN - KK], d[NN - KK + 2], l[NN - KK + 2], u_lu[NN - KK + 2], s[NN - KK + 1]; int count = 0, syn_error = 0, root[TT], loc[TT], z[TT + 1], err[NN], reg[TT + 1]; int erasures[TT * 2]; // Array to store erasure positions int erasure_count = 0; // Number of erasures err_flag = 0; // Detect erasures (positions with -1) for (i = 0; i < NN; i++) { if (recd[i] == -1) { if (erasure_count < 2 * TT) { erasures[erasure_count++] = i; } } } /* Compute syndromes */ for (i = 1; i <= NN - KK; i++) { s[i] = 0; for (j = 0; j < NN; j++) { // 修改:删除位置视为0值计算伴随式 int index_val = recd[j]; if (index_val == -1) index_val = index_of[0]; // 删除位置视为0 if (index_val != -1) { s[i] ^= alpha_to[(index_val + i * j) % NN]; } } if (s[i] != 0) syn_error = 1; s[i] = index_of[s[i]]; } if (syn_error) { err_flag = 1; d[0] = 0; d[1] = s[1]; elp[0][0] = 0; elp[1][0] = 1; for (i = 1; i < NN - KK; i++) { elp[0][i] = -1; elp[1][i] = 0; } l[0] = 0; l[1] = 0; u_lu[0] = -1; u_lu[1] = 0; u = 0; // Initialize with erasures if any if (erasure_count > 0) { l[1] = erasure_count; elp[1][0] = 1; // σ_0 = 1 // σ(x) = ∏_{i=0}^{v-1} (1 - X_i x) for (i = 0; i < erasure_count; i++) { int Xi = erasures[i]; // X_i = α^(erasures[i]) is not used directly int alpha_Xi = alpha_to[Xi]; // actual element value for (j = l[1]; j > 0; j--) { // 使用域元素乘法而不是指数的加法 if (elp[1][j-1] != -1) { int temp = index_of[elp[1][j-1]]; if (temp != -1) { elp[1][j] ^= alpha_to[(temp + Xi) % NN]; } } } // Also multiply the constant term if (elp[1][0] != -1) { int temp = index_of[elp[1][0]]; if (temp != -1) { elp[1][0] = alpha_to[(temp + Xi) % NN]; } } } // Compute initial discrepancy if (s[1] != -1) { d[1] = alpha_to[s[1]]; for (i = 1; i <= erasure_count; i++) { if (elp[1][i] != 0) { int temp = index_of[elp[1][i]]; if (temp != -1) { d[1] ^= alpha_to[(temp + i) % NN]; } } } d[1] = index_of[d[1]]; } else { d[1] = -1; } } do { u++; if (d[u] == -1) { l[u + 1] = l[u]; for (i = 0; i <= l[u]; i++) { elp[u + 1][i] = elp[u][i]; elp[u][i] = index_of[elp[u][i]]; } } else { q = u - 1; while ((d[q] == -1) && (q > 0)) q--; if (q > 0) { j = q; do { j--; if ((d[j] != -1) && (u_lu[q] < u_lu[j])) q = j; } while (j > 0); } if (l[u] > l[q] + u - q) l[u + 1] = l[u]; else l[u + 1] = l[q] + u - q; for (i = 0; i < NN - KK; i++) elp[u + 1][i] = 0; for (i = 0; i <= l[q]; i++) { if (elp[q][i] != -1) { elp[u + 1][i + u - q] = alpha_to[(d[u] + NN - d[q] + elp[q][i]) % NN]; } } for (i = 0; i <= l[u]; i++) { elp[u + 1][i] ^= elp[u][i]; elp[u][i] = index_of[elp[u][i]]; } } u_lu[u + 1] = u - l[u + 1]; if (u < NN - KK) { if (s[u + 1] != -1) d[u + 1] = alpha_to[s[u + 1]]; else d[u + 1] = 0; for (i = 1; i <= l[u + 1]; i++) { if (elp[u + 1][i] != 0) { int temp = index_of[elp[u + 1][i]]; if (temp != -1 && s[u + 1 - i] != -1) { d[u + 1] ^= alpha_to[(s[u + 1 - i] + temp) % NN]; } } } d[u + 1] = index_of[d[u + 1]]; } } while ((u < NN - KK) && (l[u + 1] <= TT + erasure_count)); u++; if (l[u] <= TT + erasure_count) { for (i = 0; i <= l[u]; i++) elp[u][i] = index_of[elp[u][i]]; for (i = 1; i <= l[u]; i++) reg[i] = elp[u][i]; count = 0; for (i = 1; i <= NN; i++) { q = 1; for (j = 1; j <= l[u]; j++) { if (reg[j] != -1) { reg[j] = (reg[j] + j) % NN; q ^= alpha_to[reg[j]]; } } if (!q) { root[count] = i; loc[count] = NN - i; count++; } } if (count == l[u]) { for (i = 1; i <= l[u]; i++) { if (s[i] != -1) z[i] = alpha_to[s[i]]; else z[i] = 0; for (j = 1; j < i; j++) { if (elp[u][i - j] != -1 && s[j] != -1) { z[i] ^= alpha_to[(elp[u][i - j] + s[j]) % NN]; } } z[i] = index_of[z[i]]; } for (i = 0; i < NN; i++) { err[i] = 0; if (recd[i] != -1) recd[i] = alpha_to[recd[i]]; else recd[i] = 0; } // 正确的Forney算法实现 for (i = 0; i < count; i++) { // 分子计算 err[loc[i]] = alpha_to[z[1]]; for (j = 2; j <= count; j++) { if (z[j] != -1) { err[loc[i]] ^= alpha_to[(z[j] + j * root[i]) % NN]; } } if (err[loc[i]] != 0) { // 转换为指数形式 err[loc[i]] = index_of[err[loc[i]]]; // 分母计算 - 使用经典实现 q = 0; /* form denominator of error term */ for (j = 0; j < count; j++) { if (j != i) { // 计算 1 - X_j * X_i^{-1} = 1 - α^{loc[j] - loc[i]} int diff = (loc[j] - loc[i] + NN) % NN; int term = 1 ^ alpha_to[diff]; q = (q + index_of[term]) % NN; } } // 最终错误值计算 err[loc[i]] = alpha_to[(err[loc[i]] - (q + loc[i]) + 2 * NN) % NN]; // 纠正错误 recd[loc[i]] ^= err[loc[i]]; } } } else { err_flag = 2; for (i = 0; i < NN; i++) { if (recd[i] != -1) recd[i] = alpha_to[recd[i]]; else recd[i] = 0; } } } else { err_flag = 2; for (i = 0; i < NN; i++) { if (recd[i] != -1) recd[i] = alpha_to[recd[i]]; else recd[i] = 0; } } } else { for (i = 0; i < NN; i++) { if (recd[i] != -1) recd[i] = alpha_to[recd[i]]; else recd[i] = 0; } } // 重新计算伴随式以验证校正是否成功 int syn_error_after = 0; for (i = 1; i <= NN - KK; i++) { int s_after = 0; for (j = 0; j < NN; j++) { int index_val = index_of[recd[j]]; if (index_val == -1) continue; s_after ^= alpha_to[(index_val + i * j) % NN]; } if (s_after != 0) { syn_error_after = 1; break; } } if (syn_error_after) { err_flag = 2; // 校正失败 } } int main() { register int i; int acterr_num, err_pos[NN]; srand((unsigned int)time(NULL)); // Initialize random seed /* generate the Galois Field GF(2**MM) */ generate_gf(); /* compute the generator polynomial */ gen_poly(); do { // ====== 重置全局状态 ====== memset(data, 0, sizeof(data)); memset(bb, 0, sizeof(bb)); memset(recd, 0, sizeof(recd)); err_flag = 0; // ========================= printf("\nReed-Solomon code is (%d,%d) over GF(2^%d).\n", NN, KK, MM); printf("This can correct up to %d errors.\n", TT); printf("\nEnter number of errors to inject (0-%d): ", TT); scanf_s("%d", &acterr_num); if (acterr_num > TT) { printf("Error: Maximum %d errors can be corrected\n", TT); continue; } if (acterr_num > 0) { printf("Enter positions of errors (0-%d):\n", NN - 1); for (i = 0; i < acterr_num; i++) { printf("Error %d position: ", i + 1); scanf_s("%d", &err_pos[i]); if (err_pos[i] < 0 || err_pos[i] >= NN) { printf("Invalid position! Must be 0-%d\n", NN - 1); i--; } } } // Generate test data for (i = 0; i < KK; i++) data[i] = rand() % (NN + 1); // Backup original data before encoding dtype original_data[KK]; memcpy(original_data, data, sizeof(data)); printf("\nOriginal data (first 10 symbols):\n"); for (i = 0; i < 10 && i < KK; i++) printf("%d ", data[i]); printf("\n"); // Encode data encode_rs(); // Form transmitted codeword for (i = 0; i < NN - KK; i++) recd[i] = bb[i]; for (i = NN - KK; i < NN; i++) recd[i] = data[i - (NN - KK)]; // Make a copy for decoding int recd_copy[NN]; for (i = 0; i < NN; i++) recd_copy[i] = recd[i]; // Inject errors printf("\nInjecting %d errors...\n", acterr_num); for (i = 0; i < acterr_num; i++) { int pos = err_pos[i]; int orig_val = recd[pos]; // 确保错误值在有效范围内 int error_val = (rand() % (NN - 1)) + 1; // 1 to NN-1 // 使用异或操作注入错误 recd[pos] ^= error_val; printf(" Position %d: %d → %d (error = %d)\n", pos, orig_val, recd[pos], error_val); } // Convert to index form for decoding int recd_index[NN]; for (i = 0; i < NN; i++) { recd_index[i] = recd[i]; recd[i] = index_of[recd[i]]; } // Decode decode_rs(); // Print decoding result switch (err_flag) { case 0: printf("\nStatus: No errors detected\n"); break; case 1: printf("\nStatus: Errors corrected successfully\n"); break; case 2: printf("\nStatus: Too many errors to correct\n"); break; } // Print decoded data (first 10 symbols) - now from recd array printf("\nDecoded data (first 10 symbols):\n"); for (i = NN - KK; i < NN - KK + 10 && i < NN; i++) printf("%d ", recd[i]); printf("\n"); // Print original data (first 10 symbols) from backup printf("Original data (first 10 symbols):\n"); for (i = 0; i < 10 && i < KK; i++) printf("%d ", original_data[i]); printf("\n"); // Verify decoding - Compare decoded data with original data int errors_data = 0; for (i = 0; i < KK; i++) { int decoded_value = recd[i + (NN - KK)]; if (decoded_value != original_data[i]) { errors_data++; printf("Data position %d: Original=%d, Decoded=%d\n", i + (NN - KK), original_data[i], decoded_value); } } // Verify parity symbols int errors_parity = 0; for (i = 0; i < NN - KK; i++) { if (recd[i] != recd_copy[i]) { errors_parity++; printf("Parity position %d: Original=%d, Decoded=%d\n", i, recd_copy[i], recd[i]); } } if (errors_data == 0 && errors_parity == 0) { printf("\nVerification: ALL symbols match original!\n"); } else { printf("\nVerification: %d data symbols and %d parity symbols differ from original\n", errors_data, errors_parity); } printf("\nPress ESC to exit, any other key to continue..."); } while (_getch() != 27); return 0; }
最新发布
08-12
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值