暴力枚举每一位是否进位,然后就可以高斯消元解出方程了。然而复杂度是O(2nn3),相当不靠谱。

  考虑优化。注意到某一位进位情况的变化只会影响到方程的常数项,于是可以在最开始做一次高斯消元算出每个未知数与每个常数项的关系。这样就变成了O(2nn2),虽然仍然不靠谱不过经常可以早早break,就能过了。

  似乎有一些挺麻烦的地方怎么都调不对,后来就变成了面向代码编程也不知道改了什么最后几乎全一样了才过。事实上还是有bug的,比如2 AB BA AA这样的数据会re掉,原因是方程看似解不出来但是有所有数不同的限制,应该还要特判一下然而懒得写了。
  当然这本来是个剪枝题。

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
int read()
{
int x=,f=;char c=getchar();
while (c<''||c>'') {if (c=='-') f=-;c=getchar();}
while (c>=''&&c<='') x=(x<<)+(x<<)+(c^),c=getchar();
return x*f;
}
#define N 30
int n,m,a[N],b[N],c[N],f[N][N],d[N][N],u[N];
bool flag[N];
int gcd(int n,int m){return m==?n:gcd(m,n%m);}
void gauss()
{
for (int i=;i<=n;i++) d[i][i-]=-,d[i][i]=n;
for (int i=;i<=n;i++)
f[i][c[i]]--,f[i][a[i]]++,f[i][b[i]]++;
for (int i=,t=;i<=n&&t<=n;i++,t++)
{
int mx=i;
for (int j=i+;j<=n;j++)
if (abs(f[j][t])>abs(f[mx][t])) mx=j;
if (mx!=i) swap(f[i],f[mx]),swap(d[i],d[mx]);
if (!f[i][t]) {i--;continue;}
for (int j=;j<=n;j++)
if (i!=j&&f[j][t])
{
int x=f[j][t]/gcd(f[j][t],f[i][t]),y=f[i][t]/gcd(f[j][t],f[i][t]);
for (int k=;k<=n;k++)
f[j][k]=f[j][k]*y-f[i][k]*x,
d[j][k]=d[j][k]*y-d[i][k]*x;
}
}
}
void print()
{
int a[N]={};
for (int i=;i<=n;i++)
{
for (int j=;j<=n;j++)
a[i]+=d[i][j]*u[j];
a[i]/=f[i][i];
}
for (int i=;i<=n;i++) cout<<a[i]<<' ';
exit();
}
void check()
{
memset(flag,,sizeof(flag));
for (int i=;i<=n;i++)
{
int x=;
for (int j=;j<=n;j++) x+=d[i][j]*u[j];
if (x%f[i][i]) return;
x/=f[i][i];
if (x<||x>=n||flag[x]) return;
flag[x]=;
}
print();
}
void dfs(int k)
{
if (k==n) check();
else u[k]++,dfs(k+),u[k]--,dfs(k+);
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("calc.in","r",stdin);
freopen("calc.out","w",stdout);
const char LL[]="%I64d\n";
#else
const char LL[]="%lld\n";
#endif
n=read();
char ch=getchar();while (ch<'A'||ch>'Z') ch=getchar();
for (int i=;i<=n;i++) m=max(m,a[i]=ch-'A'+),ch=getchar();
while (ch<'A'||ch>'Z') ch=getchar();
for (int i=;i<=n;i++) m=max(m,b[i]=ch-'A'+),ch=getchar();
while (ch<'A'||ch>'Z') ch=getchar();
for (int i=;i<=n;i++) m=max(m,c[i]=ch-'A'+),ch=getchar();
reverse(a+,a+n+),reverse(b+,b+n+),reverse(c+,c+n+);
gauss();
dfs();
return ;
}

Luogu1092 NOIP2004虫食算(搜索+高斯消元)的更多相关文章

  1. [BZOJ1902]:[NOIP2004]虫食算(搜索)

    题目传送门 题目描述 所谓虫食算,就是原先的算式中有一部分被虫子啃掉了,需要我们根据剩下的数字来判定被啃掉的字母. 来看一个简单的例子: 43#98650#45+8468#6633=444455069 ...

  2. NOIP2004 虫食算

    描述 所谓虫食算,就是原先的算式中有一部分被虫子啃掉了,需要我们根据剩下的数字来判定被啃掉的字母.来看一个简单的例子:43#9865#045+ 8468#6633= 44445506678其中#号代表 ...

  3. [题解](折半搜索/高斯消元枚举自由元)BZOJ_1770_Lights

    状压,时间空间都不行,如果每次搜索一半就可以省下很多空间,用map记下每种状态的答案,最后再把两次的答案合并 然而正解是高斯消元解异或方程组,最后搜索自由元 #include<iostream& ...

  4. [Noip2004]虫食算 dfs

    搜索问题的关键:优秀的搜索策略以及行之有效的减枝 对于这道题我们阶乘搜肯定不行所以我们按位搜,我们对每一位的三个数进行赋值,然后判解. 对于此一类的搜索乘上一个几十的常数来减枝往往要比直接搜要快得多, ...

  5. P1092 虫食算[搜索]

    这个式子是是由\(A\sim A+N\)组成的,那么\(A\sim A+N\)就只能等于\(0\sim N-1\),因此我们每次对\(A\sim A+N\)的取值做一个新的排列,然后judge一下当前 ...

  6. VIJOS 1052贾老二算算术 (高斯消元)

    描述 贾老二是个品学兼优的好学生,但由于智商问题,算术学得不是很好,尤其是在解方程这个方面.虽然他解决 2x=2 这样的方程游刃有余,但是对于 {x+y=3 x-y=1} 这样的方程组就束手无策了.于 ...

  7. NOIP 2004 虫食算题解

    问题 E: [Noip2004]虫食算 时间限制: 1 Sec  内存限制: 128 MB 题目描述 所谓虫食算,就是原先的算式中有一部分被虫子啃掉了,需要我们根据剩下的数字来判定被啃掉的字母.来看一 ...

  8. 【算法】高斯消元&线性代数

    寒假作业~就把文章和题解3道题的代码扔在这里啦——链接: https://pan.baidu.com/s/1kWkGnxd 密码: bhh9 1.HNOI2013游走 #include <bit ...

  9. [NOIP2004] 提高组 洛谷P1092 虫食算

    题目描述 所谓虫食算,就是原先的算式中有一部分被虫子啃掉了,需要我们根据剩下的数字来判定被啃掉的字母.来看一个简单的例子: 43#9865#045 +8468#6633 44445509678 其中# ...

随机推荐

  1. 北京Uber优步司机奖励政策(2月20日~2月21日)

    滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...

  2. Java:多线程中的volatile

    一.为什么使用volatile 首先,通过一段简单的代码来理解为什么要使用volatile: public class RunThread extends Thread{ private boolea ...

  3. nio之netty3的应用

    1.netty3是nio的封装版本.在使用上面比nio的直接使用更好.nio简单使用都是单线程的方式(比如:一个服务员服务很多客户),但是netty3的方式不一样的是,引入线程池的方式来实现服务的通信 ...

  4. CC3200底板测试-烧写CC3200-LAUNCHXL

    1. 拿到板子,先研究一下几个跳线帽的作用.我在底板上测到VCC_DCDC_3V3和VCC_BRD之间应该有一个跳线帽的,但是在原理上找不到. 2. LED灯的用途,测试的时候,发现这个灯有时候亮,有 ...

  5. thinkphp5

    分页: thinkphp5分页默认只带page参数 在使用form表单method='get'传递关键字来筛选: 保证每次刷新依旧带上筛选参数 但遇到分页时,下面的分页默认自带page,没有之前筛选的 ...

  6. libevent学习七(bufferevent)

    1. 每个bufferevent 都拥有类型为struct evbuffer的input buffer和out buffer,分别供数据读取和数据写入使用. 2.读取和写入数据是通过编写和设置对应的回 ...

  7. leetcode-汉明距离

    汉明距离 两个整数之间的汉明距离指的是这两个数字对应二进制位不同的位置的数目. 给出两个整数 x 和 y,计算它们之间的汉明距离. 注意: 0 ≤ x, y < 231. 示例: 输入: x = ...

  8. Visaul Studio 密钥

    vs professional 2015 简体中文版  :HMGNV-WCYXV-X7G9W-YCX63-B98R2

  9. Click Once使用总结

    做了一个CS结构软件,有十几个用户使用的客户端,因为刚开始试用期间,要不断根据用户使用情况修正问题和添加新功能,所以频繁更新是不可避免的,暂时没有深入去研究软件更新,暂时采取的方式是用户通过FTP自行 ...

  10. hadoop3.0新特性及新功能

    Hadoop-3.0.0-alpha2版本发布,相比之前的hadoop-2.x有一系列的功能增强.但目前还是个alpha版本,有很多bug,且不能保证API的稳定和质量. 主要变化 Java最低版本要 ...