题目链接:Palindromic Paths

题意:

给你一个n行m列的矩阵,这个矩阵被0或者1所填充,你需要从点(1,1)走到点(n,m)。这个时候会有很多路径,每一条路径对应一个01串,你可以改变这个矩阵中某些位置的值,你需要保证改变之后每一条路径串都是回文串。

最后输出你最少需要改变多少位置

题解:

因为你要保证每一条路径都是回文路径,那么如下面这组样例:

3 5
1 0 1 0 0
1 1 1 1 0
0 0 1 0 0

起点位置(1,1)的值是1但是终点位置(n,m)的值是0,但是在一条路径串上面这两个点必须是串的起点和终点,那么如果这条串要变成回文串,那么这两个位置的值就必须相等。其他位置也是一样,比如路径串的第二个位置的值需要和串的倒数第二个位置的值相等。

那么我们只需要让这个串的第二步走的所有位置的值和倒数第二步走的所有位置的值相等就行。例如上面的例子:

第一步:我们需要把(1,1)和(n,m)的值变成相同,共有1个0,1个1,那么都变成1也行,变成0也行

第二步:串的第一个位置是(1,1),那么第二步可以走到(1,2)和(2,1)。串的倒数第一个位置是(n,m),那么倒数第二步可以走到(n-1,m)和(n,m-1)这两个位置

我们发现这四个位置共有3个0,1个1。因为我们必须要把它们变成一样的且题目要求输出最小改变的位置数量,那么我们可以让1变成0就可以了

第三步:和上面差不多

代码实现我用了两个队列r1和r2,r1是从起点(1,1)开始进行bfs,r2是从终点(n,m)开始bfs遍历。每次r1和r2都向前遍历一个层次就统计一样0和1的个数。判断一下是0变1还是1变0

我们要注意这个遍历过程要有一个终止位置,比如下面这组样例

2 2
1 1
0 1

对于(1,2)位置和(2,1)位置我们就不需要要求它们必须相同,因为这个串的长度肯定是一个奇数,那么不管串中间那个位置是0还是1都不会造成影响,所以就不用管

所以再从起点和终点两个位置同时进行遍历只需要ans次,ans计算如下:

1 int num=(m-1)+(n-1),ans;
2 num%2==0?ans=num/2-1:ans=num/2;

代码:

  1 #include<stdio.h>
2 #include<algorithm>
3 #include<iostream>
4 #include<string>
5 #include<queue>
6 #include<deque>
7 #include<string.h>
8 #include<map>
9 #include <iostream>
10 #include <math.h>
11 using namespace std;
12 typedef long long ll;
13 const int maxn=35;
14 struct shudui
15 {
16 int x,y,val,type;
17 } str1,str2;
18 int w[maxn][maxn],n,m,sum,vis[maxn][maxn];
19 int p[2][2]=
20 {
21 {0,1},
22 {1,0}
23 };
24 queue<shudui>r1,r2;
25 void bfs(int ci)
26 {
27 int zero,one;
28 for(int k=0; k<ci; ++k)
29 {
30 zero=one=0;
31 while(!r1.empty())
32 {
33 str1=r1.front();
34 if(str1.type==k)
35 {
36 r1.pop();
37 for(int i=0; i<2; ++i)
38 {
39 int xx=str1.x+p[i][0];
40 int yy=str1.y+p[i][1];
41 if(xx>=1 && xx<=n && yy>=1 && yy<=m && vis[xx][yy]==0)
42 {
43 //printf("***\n");
44 str2.x=xx;
45 str2.y=yy;
46 str2.type=str1.type+1;
47 str2.val=w[xx][yy];
48 //printf("%d %d**\n",xx,yy);
49 vis[xx][yy]=1;
50 if(w[xx][yy])
51 {
52 one++;
53 }
54 else zero++;
55 r1.push(str2);
56 }
57 }
58 }
59 else break;
60 }
61
62 while(!r2.empty())
63 {
64 str1=r2.front();
65 if(str1.type==k)
66 {
67 r2.pop();
68 for(int i=0; i<2; ++i)
69 {
70 int xx=str1.x-p[i][0];
71 int yy=str1.y-p[i][1];
72 if(xx>=1 && xx<=n && yy>=1 && yy<=m && vis[xx][yy]==0)
73 {
74
75 str2.x=xx;
76 str2.y=yy;
77 str2.type=str1.type+1;
78 str2.val=w[xx][yy];
79 //printf("%d %d**\n",xx,yy);
80 vis[xx][yy]=1;
81 if(w[xx][yy])
82 {
83 one++;
84 }
85 else zero++;
86 r2.push(str2);
87 }
88 }
89 }
90 else break;
91 }
92 //printf("%d %d\n---------------\n\n\n",zero,one);
93 sum+=min(zero,one);
94 }
95 // if(m%2)
96 // {
97 // zero=one=0;
98 // while(!r1.empty())
99 // {
100 // if(r1.front().val)
101 // one++;
102 // else zero++;
103 // r1.pop();
104 // }
105 // sum+=min(zero,one);
106 // }
107 }
108 int main()
109 {
110 int t;
111 scanf("%d",&t);
112 while(t--)
113 {
114 while(!r1.empty()) r1.pop();
115 while(!r2.empty()) r2.pop();
116 memset(vis,0,sizeof(vis));
117 memset(w,0,sizeof(w));
118 sum=0;
119 scanf("%d%d",&n,&m);
120 for(int i=1; i<=n; ++i)
121 {
122 for(int j=1; j<=m; ++j)
123 {
124 scanf("%d",&w[i][j]);
125 }
126 }
127 // if(n==m && n==2)
128 // {
129 // printf("0\n");
130 // continue;
131 // }
132 str1.type=0;
133 str1.val=w[1][1];
134 vis[1][1]=vis[n][m]=1;
135 str1.x=str1.y=1;
136 r1.push(str1);
137 str1.x=n;
138 str1.y=m;
139 str1.val=w[n][m];
140 r2.push(str1);
141 int num=(m-1)+(n-1),ans;
142 num%2==0?ans=num/2-1:ans=num/2;
143 bfs(ans);
144 if(w[1][1]!=w[n][m]) sum++;
145 printf("%d\n",sum);
146 }
147 return 0;
148 }

Educational Codeforces Round 89 (Rated for Div. 2) C Palindromic Paths的更多相关文章

  1. Educational Codeforces Round 89 (Rated for Div. 2) C. Palindromic Paths(贪心)

    题目链接:https://codeforces.com/contest/1366/problem/C 题意 有一个 $n \times m$ 的 $01$迷宫,要使从 $(1,1)$ 到 $(n,m) ...

  2. Educational Codeforces Round 89 (Rated for Div. 2) C. Palindromic Paths (思维)

    题意:有一个\(n\)x\(m\)的矩阵,从\((1,1)\)出发走到\((n,m)\),问最少修改多少个数,使得所有路径上的数对应相等(e.g:\((1,2)\)和\((n-1,m)\)或\((2, ...

  3. Educational Codeforces Round 89 (Rated for Div. 2) B. Shuffle(数学/双指针)

    题目链接:https://codeforces.com/contest/1366/problem/B 题意 大小为 $n$ 的数组 $a$,除了 $a_x = 1$,其余 $a_i = 0$,依次给出 ...

  4. Educational Codeforces Round 89 (Rated for Div. 2) A. Shovels and Swords(贪心/数学)

    题目链接:https://codeforces.com/contest/1366/problem/A 题意 有两个数 $a$ 和 $b$,每次可以选择从一个数中取 $2$,另一个数中取 $1$,问最多 ...

  5. Educational Codeforces Round 89 (Rated for Div. 2) A Shovels and Swords B、Shuffle

    题目链接:A.Shovels and Swords 题意: 你需要一个木棍和两个钻石可以造出来一把剑 你需要两个木棍和一个钻石可以造出来一把铁锹 你现在有a个木棍,b个钻石,问你最多可以造出来几件东西 ...

  6. Educational Codeforces Round 89 (Rated for Div. 2)D. Two Divisors 线性筛质因子

    题目链接:D:Two Divisors 题意: 给你n个数,对于每一个数vi,你需要找出来它的两个因子d1,d2.这两个因子要保证gcd(d1+d2,vi)==1.输出的时候输出两行,第一行输出每一个 ...

  7. Educational Codeforces Round 89 (Rated for Div. 2) A. Shovels and Swords (贪心)

    题意:你有\(a\)个树枝和\(b\)个钻石,\(2\)个树枝和\(1\)个钻石能造一个铁铲,\(1\)个树枝和\(2\)个钻石能造一把剑,问最多能造多少铲子和剑. 题解:如果\(a\le b\),若 ...

  8. Educational Codeforces Round 89 (Rated for Div. 2) D. Two Divisors (数学)

    题意:有\(n\)组数,对于每组数,问是否能找到两个因子\(d_{1},d{2}\),使得\(gcd(d_{1}+d_{2},a_{i}=1)\),如果有,输出它们,否则输出\(-1\). 题解:对于 ...

  9. Educational Codeforces Round 89 (Rated for Div. 2) B. Shuffle (数学,区间)

    题意:有长为\(n\)的排列,其中\(x\)位置上的数为\(1\),其余位置全为\(0\),询问\(m\)次,每次询问一个区间,在这个区间内可以交换任意两个位置上的数,问\(1\)最后出现在不同位置的 ...

随机推荐

  1. 【Git】简易使用教程

    Git简介 诞生 简单的来说,就是为了托管庞大的Linux源码,开始选择了商用的版本控制系统BitKeeper,但是因为一系列操作,BitKeeper不让用了,所以Linus花了两周时间自己用C写了一 ...

  2. 开源:AspNetCore 应用程序热更新升级工具(全网第一份公开的解决方案)

    1:下载.开源.使用教程 下载地址:Github 下载 .其它下载 开源地址:https://github.com/cyq1162/AspNetCoreUpdater 使用教程: 解压AspNetCo ...

  3. wpf 中用 C# 代码创建 PropertyPath ,以对间接目标进行 Storyboard 动画.

    如图,一个 Rectangle 一个 Button ,点击按钮时要通过动画完成对 Rectangle填充色的渐变动画. Xaml: 1 <Window 2 x:Class="WpfAp ...

  4. Sentry(v20.12.1) K8S 云原生架构探索,SENTRY FOR JAVASCRIPT 故障排除

    系列 Sentry-Go SDK 中文实践指南 一起来刷 Sentry For Go 官方文档之 Enriching Events Snuba:Sentry 新的搜索基础设施(基于 ClickHous ...

  5. 力软最新版本与.netCore版本

    功能强大,直接上图: 加微信或QQ交流开发技术:25489181 netcore版本 版本优势: .NET Core是适用于 Windows.Linux 和 macOS 的免费.开源托管的计算机软件框 ...

  6. logicaldisk本地磁盘管理

    在网上搜了很多,但是基本都是一样的,差不多都是互相转载摘抄,就那么几个寥寥无几的例子,所以我冒了很大的风险,自己经过多次的测试,对这个命令有了一些新的认识!拿出来分享一下! LOGICALDISK   ...

  7. OAuth2.0是干什么的?

    OAuth2.0是干什么的? 首先用户有一些数据: 将数据存储在服务器上: 这时候有一个应用要访问数据: 如果这个应用是一个恶意程序呢?所以需要一个检验来判断请求是不是安全的: 如何判断是不是安全的? ...

  8. 浅谈linux IO csy 360技术 2021-01-18

    浅谈linux IO csy 360技术 2021-01-18

  9. Python_1生成器(下)之单线并行--生产着消费者模型

    1 import time 2 def consumer(name): 3 print('%s准备吃包子了!' %name) 4 while True: 5 baozi = yield 6 print ...

  10. 思考gRPC :为什么是HTTP/2

    Introducing gRPC Support with NGINX 1.13.10 - NGINX https://www.nginx.com/blog/nginx-1-13-10-grpc/ 思 ...