• 第十四周 11.29-12.5


    11.29-12.2

    什么都没干。

    12.3

    偷的一个题目。

    题意:

    给一个N*N(N为偶数,N<=3000)的棋盘,上面放满黑白两面的棋子,我们用O表示白X表示黑,初始状态都是黑向上。

    一次操作是选择一个棋子,与其同行或者同列的所有棋子(包括自己)翻面。

    给一个最终局面,问:进行了几次操作?选择的是哪几个点?

    分析:

    首先选择的点在最终局面上一定是白子。

    其次,对于最终局面的所有白子,无非两种情况。

    1.操作中选择了这个子,并将与其同行同列的子翻转。

    2.操作中选择了与这个子同行(列)的一个子翻转。

    但是这两种白子具有区别。

    由1.形成的白子其同行中的白子数等于其同列中的白子数。

    简证:考虑初始局面,任意选一个位置翻,再选第二个位置翻的时候,必然与第一个子所在的行列都有且仅有一个交点。

       也就是使第一个子的行列都减少一个白子,同时我们注意到所有被选择翻的子其行列的白子数都是相等的,继续

       归纳即可。

    由2.形成的白子其行列白子差为奇数,类似1.的方法来说明即可。

    结论:在最终局面上寻找所有行列白子数相等的白子即为答案。

    简陋datamaker

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <cstdlib>
     5 #include <ctime>
     6 #include <algorithm>
     7 using namespace std;
     8 const int maxn = 3030;
     9 char G[maxn][maxn];
    10 int visx[maxn], visy[maxn];
    11 
    12 void init(int n)
    13 {
    14     memset(visx, 0, sizeof(visx));
    15     memset(visy, 0, sizeof(visy));
    16     for(int i = 1; i <= n; i++)
    17         for(int j = 1; j <= n; j++)
    18             G[i][j] = 'X';
    19     return;
    20 }
    21 
    22 void change(int n, int x, int y)
    23 {
    24     G[x][y] = G[x][y] == 'O' ? 'X' : 'O';
    25     for(int i = 1; i <= n; i++)
    26     {
    27         if(i != y) G[x][i] = G[x][i] == 'O' ? 'X' : 'O';
    28         if(i != x) G[i][y] = G[i][y] == 'O' ? 'X' : 'O';
    29     }
    30     return;
    31 }
    32 
    33 void Print(int n)
    34 {
    35     printf("%d
    ", n);
    36     for(int i = 1; i <= n; i++)
    37     {
    38         for(int j = 1; j <= n; j++)
    39             printf("%c", G[i][j]);
    40         puts("");
    41     }
    42     return;
    43 }
    44 
    45 int main(void)
    46 {
    47     srand(time(NULL));
    48     freopen("data.txt","w",stdout);
    49     FILE * f_out = fopen("ans.txt","w");
    50     int T = 100, N = 3000;
    51     printf("%d
    ", T);
    52     for(int i = 1; i <= T; i++)
    53     {
    54         int n = 1;
    55         while( n % 2 == 1 ) n = rand() % (N - 1) + 1;
    56         init(n);
    57         int k = rand() % (n + 1), cnt = 0;
    58         for(int j = 1; j <= 10000; j++)
    59         {
    60             if(cnt == k) break;
    61             int x = rand() % (n - 1) + 1, y =  rand() % (n - 1) + 1;
    62             if(visx[x] || visy[y]) continue;
    63             cnt++;
    64             visx[x] = visy[y] = 1;
    65             change(n, x, y);
    66         }
    67         Print(n);
    68         fprintf(f_out, "%d
    ", min(k,cnt));
    69     }
    70     fclose(f_out);
    71     return 0;
    72 }
    Aguin

    简陋solver

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <vector>
     5 #include <algorithm>
     6 using namespace std;
     7 typedef pair<int,int> pii;
     8 const int maxn = 3030;
     9 char G[maxn][maxn];
    10 int cntx[maxn], cnty[maxn];
    11 
    12 bool cmp(pii A, pii B)
    13 {
    14     if(A.first != B.first) return A.first < B.first;
    15     return A.second < B.second;
    16 }
    17 
    18 int main(void)
    19 {
    20     freopen("data.txt","r",stdin);
    21     freopen("out.txt","w",stdout);
    22     int T;
    23     scanf("%d", &T);
    24     while(T--)
    25     {
    26         int N;
    27         scanf("%d", &N);
    28         for(int i = 1; i <= N; i++)
    29             scanf("%s", G[i] + 1);
    30 
    31         memset(cntx, 0, sizeof(cntx));
    32         memset(cnty, 0, sizeof(cnty));
    33 
    34         for(int i = 1; i <= N; i++)
    35             for(int j = 1; j <= N; j++)
    36                 if(G[i][j] == 'O') cntx[i]++, cnty[j]++;
    37 
    38         vector<pii> ans;
    39         for(int i = 1; i <= N; i++)
    40         {
    41             for(int j = 1; j <= N; j++)
    42             {
    43                 if(G[i][j] != 'O' || cntx[i] != cnty[j]) continue;
    44                 ans.push_back(pii(i,j));
    45             }
    46         }
    47 
    48         int L = ans.size();
    49         printf("%d
    ", L);
    50         if(L)
    51         {
    52             for(int i = 0; i < L; i++) printf("%d %d ", ans[i].first, ans[i].second);
    53             puts("");
    54         }
    55     }
    56     return 0;
    57 }
    Aguin

    简陋judge

     1 #include <iostream>
     2 #include <cstdio>
     3 using namespace std;
     4 const int maxn = 3030;
     5 char G[maxn][maxn];
     6 
     7 void change(int n, int x, int y)
     8 {
     9     G[x][y] = G[x][y] == 'O' ? 'X' : 'O';
    10     for(int i = 1; i <= n; i++)
    11     {
    12         if(i != y) G[x][i] = G[x][i] == 'O' ? 'X' : 'O';
    13         if(i != x) G[i][y] = G[i][y] == 'O' ? 'X' : 'O';
    14     }
    15     return;
    16 }
    17 
    18 bool judge(int n)
    19 {
    20     for(int i = 1; i <= n; i++)
    21             for(int j = 1; j <= n; j++)
    22                 if(G[i][j] != 'X') return false;
    23     return true;
    24 }
    25 
    26 void Print(int n)
    27 {
    28     printf("%d
    ", n);
    29     for(int i = 1; i <= n; i++)
    30     {
    31         for(int j = 1; j <= n; j++)
    32             printf("%c",G[i][j]);
    33         puts("");
    34     }
    35     return;
    36 }
    37 
    38 int main(void)
    39 {
    40     FILE * f_in = fopen("data.txt","r");
    41     FILE * f_ans = fopen("ans.txt","r");
    42     FILE * f_user = fopen("out.txt","r");
    43     int T;
    44     fscanf(f_in, "%d", &T);
    45     int ok = 1;
    46     for(int kase = 1; kase <= T; kase++)
    47     {
    48         int N;
    49         fscanf(f_in, "%d", &N);
    50         for(int i = 1; i <= N; i++)
    51             fscanf(f_in, "%s", G[i] + 1);
    52 
    53         int k, ans;
    54         fscanf(f_user, "%d", &k);
    55         fscanf(f_ans, "%d", &ans);
    56 
    57         for(int i = 1; i <= k; i++)
    58         {
    59             int x, y;
    60             fscanf(f_user ,"%d%d",&x, &y);
    61             change(N, x, y);
    62         }
    63 
    64         if(k != ans) {ok = 0; printf("%d
    ", kase);}
    65         if(!judge(N)) {ok = 0; printf("%d
    ", kase);}
    66         //Print(N);
    67     }
    68     puts(ok ? "AC" : "WA");
    69     fclose(f_in);
    70     fclose(f_ans);
    71     fclose(f_user);
    72     return 0;
    73 }
    Aguin

    如果N为奇数怎么做呢?

    容易发现,在奇数棋盘中,对于上述的1.与2.也有一些性质。

    由1.形成的白子,行列白子差为0,行列白子和为2n-2k+2(自己算两次,k为翻的次数)。

    由2.形成的白子,行列白子差为|n-1-2k|(k为翻的次数),行列白子和为n+1(自己算两次)。

    所以对于一般的情况,我们仍可以统计行列白子数来做。

    但是当满足n=2k-1时,1.与2.形成的白子行列和差全部相同,就无法用这种方法来找了。

    这个情况的做法至今没想出来。先弃了。

    12.4

    什么都没干。

    12.5

    打个BC。压线上紫。

    看自己的曲线也不是一点长进都没有吧。

  • 相关阅读:
    输入输出重定向
    进程管理
    普通变量_环境变量_环境变量配置文件
    高级文件操作命令_文件查找
    软件包管理_rpm命令管理_yum工具管理_文件归档压缩_源码包管理
    用户管理_组管理_设置主机名_UGO_文件高级权限_ACL权限
    字符串是否包含中文
    SQL 优化
    JS数组
    RedisUtil 工具类
  • 原文地址:https://www.cnblogs.com/Aguin/p/5015498.html
Copyright © 2020-2023  润新知