2017.9.7 翻硬币 失败总结

来源:互联网 发布:天音淘宝复制大师官网 编辑:程序博客网 时间:2024/06/06 00:43

这个题就是告诉你、越无从下手的题,越是数学和结论题、

这题搞了一下午+一晚上的时间,却连第一步都没想到、

因为这个题它每一个决策对其他点影响很大,所以直接从决策下手去讨论就显得非常有后效性。。

所以我们可以从关系入手、、把每个决策对其他有关决策的影响用式子表示出来

显然,对于每一个硬币,它所在的一行和所在的一列都会影响它、影响的效果是异或

所以如果最后全是0,他们的异或和是一个定值、、

就列出关系,然后就考虑怎么解

然后我们就需要消元,,这里有一个技巧:

由于n是偶数(比较后期的提示、),异或两次无效,所以我们考虑把一个点所在一行和一列的方程组写在一起、

注意到只有中间点有值、其他点都没动、

如:

0 0 0 1

1 0 1 0

0 0 0 1

0 1 0 0

考虑点 (2,3)

那我们把每个点的异或次数标上:

0(2) 0(2) 0(4) 1(2)

1(4) 0(4) 1(7) 0(4)

0(2) 0(2) 0(4) 1(2)

0(2) 1(2) 0(4) 0(2)

所以就只有(2,3)是奇数次

如果设每个点的决策为f(i,j)

那么这个点(2,3)就需要按f(2,1)^f(2,2)^f(2,3)^f(2,4)^f(1,3)^f(3,3)^f(3,4)次

所以扫一遍统计答案就可以了

所以我们考虑题有时需要根据决策入手,有时需要根据题目具有的关系入手、

根据决策入手可以考虑dp、网络流、贪心、dfs

根据关系入手可以考虑网络流、、还有这个奇怪的列方程消元、

有时候关系之间制约很明显的、有规律的就可以考虑列方程解决、、方程是把关系转化为具体的工具(就像一些解方程的题不能直观看出解一样)

%%ISA一眼秒


码(本来自己写的、后来发现可以求和优化、、就借(chao)鉴(xi)了):

#include<iostream>#include<cstdio>using namespace std;char ch[1005];int a[1005][1005],s1[1005],s2[1005],i,j,ans,n;int main(){scanf("%d",&n);for(i=0;i<n;i++){scanf("%s",ch);for(j=0;j<n;j++){a[i][j]=ch[j]-'0';s1[i]^=a[i][j];s2[j]^=a[i][j];}    }for(i=0;i<n;i++)for(j=0;j<n;j++)ans+=a[i][j]^s1[i]^s2[j];printf("%d",min(ans,n*n-ans));}









原创粉丝点击