UVALive 7511 L - Multiplication Table 数学模拟题,暴力
给定一副表,问其是否合法。
思路:当全部是?的时候,是合法的。
如果不是,那么,就找到一个数字,把它拆成若干个a*b的形式,去判断其它点是否合法即可。
拆分数字的时候,只需要枚举到sqrt(n),因为肯定是两个小于sqrt n的数相乘得到的结果。
比如6=1*6 6=2*3 注意分解后,考虑调换顺序是否合法即可。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <algorithm> using namespace std; #define inf (0x3f3f3f3f) typedef long long int LL; #include <iostream> #include <sstream> #include <vector> #include <set> #include <map> #include <queue> #include <string> const int maxn = 1000+5; struct data { LL num; int flag; } a[maxn][maxn]; struct coor { int x,y; LL num; } To_number[maxn*maxn]; int len_To_number; int n,m; void show () { for (int i=1; i<=n; ++i) { for (int j=1; j<=m; ++j) { if (a[i][j].flag) printf ("%I64d ",a[i][j].num); else printf ("? "); } printf ("\n"); } return ; } int f; int solve (int x,int y,LL num) { LL end = (LL)sqrt(num+0.5); for (LL aa=1; aa<=end; ++aa) { if (num%aa != 0) continue; LL bb = num/aa;//公差是aa int k; if (aa>=x && bb>=y) { for (k=1; k<=len_To_number; ++k) { int tx = To_number[k].x - x; int ty = To_number[k].y - y; LL ta = aa+tx, tb = bb+ty; if (ta*tb != To_number[k].num) break; } if (k == len_To_number +1) return 1; } LL taa = aa; LL tbb = bb; swap(taa,tbb); //cout<<taa<<" "<<tbb<<"--"<<endl; if (taa>=x && tbb >= y) { for (k=1; k<=len_To_number; ++k) { int tx = To_number[k].x - x; int ty = To_number[k].y - y; LL ta = taa+tx, tb = tbb+ty; if (ta*tb != To_number[k].num) break; } if (k == len_To_number +1) return 1; } } return 0; } void work () { int allque = 1; scanf("%d%d",&n,&m); int bx,by; LL number; len_To_number = 0; for (int i=1; i<=n; ++i) for (int j=1; j<=m; ++j) { char str[25]; scanf("%s",str+1); if (str[1]=='?') a[i][j].flag = 0; else { allque = 0; a[i][j].flag=1; int lenstr = strlen(str+1); a[i][j].num=0; for (int k=1; k<=lenstr; ++k) a[i][j].num = a[i][j].num*10+str[k]-'0'; bx=i; by=j; number=a[i][j].num; To_number[++len_To_number].num = a[i][j].num; To_number[len_To_number].x = i; To_number[len_To_number].y = j; } } //show(); if (allque) { printf ("Case #%d: Yes\n",++f); return ; } if (solve(bx,by,number)) { printf ("Case #%d: Yes\n",++f); return ; } else { printf ("Case #%d: No\n",++f); return ; } } int main() { #ifdef local freopen("data.txt","r",stdin); #endif int t; scanf("%d",&t); while (t--) work(); return 0; }
另外,枚举两个点的话,满足这两个点的解,就是唯一的解。也可以枚举两个点,然后确定唯一的一个解,再去比较整个地图。
不过也没什么必要。速度差不多。因为很少这样的例子,使得枚举的时候有很多个数字是满足的。
既然选择了远方,就要风雨兼程~
posted on 2016-08-19 19:22 stupid_one 阅读(589) 评论(0) 编辑 收藏 举报