UVALive 7511 Multiplication Table 水题

版权声明:本博客内容基本为原创,如有问题欢迎联系,转载请注明出处 https://blog.csdn.net/qq_41955236/article/details/84403613

题目链接:https://vj.e949.cn/64651dcc714b96f75b1cc533bde4ff55?v=1542794579

题意:

       有一个无限大乘法表,现在给你这个乘法表上一块n*m的区域,但是有一些数字可能被遗忘,问你这样一块数字能否在这个乘法表上被找到。

做法:

        如果有两个数字已知,可以用二元一次方程的来推出左上角是几行几列,那么只要验证了所有的数字是否合法,以及这一块数字的位置是否超出其原有的位置即可。

        如果只有一个数字已知,那么只要枚举它的因子,可以找到行列都小于等于当前它的行列的也就算满足条件。

代码有点 繁重 


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1000005;
const double eps=1e-9;
struct node{
    ll a,b,v;
}e[maxn];
char s[15];
ll x1,Y1,x2,y2;
int flag;
void qiu(ll a,ll b,ll c,ll &ansf,ll &anss){
    if(a==0){
        if(c%b==0){
            ansf=-(c/b);
        }
        return ;
    }
    double deta=sqrt(1.0*(b*b-4*a*c));
    ll ans1=(-b+deta)/(2*a),ans2=(-b-deta)/(2*a);
    int flag1=0;
    if(a*ans1*ans1+b*ans1+c==0&&ans1>0){
        flag1=1;
        ansf=ans1;
    }
    if(a*ans2*ans2+b*ans2+c==0&&ans2>0){
        if(flag1) anss=ans2;
        else ansf=ans1;
    }
}
int deal(){
    ll aa=e[2].a-e[1].a,bb=e[2].b-e[1].b,ans1=0,ans2=0,v1=e[1].v,v2=e[2].v;
    qiu(aa,v1-v2+aa*bb,v1*bb,ans1,ans2);
    if(ans2!=0){
        int rans=2;
        x1=v1/ans1-e[1].a+1,Y1=ans1-e[1].b+1;
        if(x1<=0||Y1<=0)
            rans--;
        x2=v1/ans2-e[1].a+1,y2=ans2-e[1].b+1;
        if(x2<=0||y2<=0)
            rans--;
        else {
            if(rans==1){
                x1=x2,Y1=y2;
            }
        }
        return rans;
    }
    else if(ans1!=0){
        x1=v1/ans1-e[1].a+1,Y1=ans1-e[1].b+1;
        if(x1<=0||Y1<=0) return 0;
        return 1;
    }
    return 0;
}
int ck(ll a,ll b,ll v,ll x,ll y){
    return v==(x+a-1)*(y+b-1);
}
int main(){
    int t,n,m,cas=0;
    cin>>t;
    while(t--){
        int now=0;
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++){
                scanf("%s",s);
                if(s[0]!='?'){
                    ++now;
                    e[now].a=i,e[now].b=j,e[now].v=(ll)atoi(s);
                }
            }
         }
         flag=0;
         if(now>=2){
            int cnt=deal();
            if(cnt){
                int flag1=0,flag2=1;
                for(int i=3;i<=now;i++){
                    if(!ck(e[i].a,e[i].b,e[i].v,x1,Y1)){
                        flag1=1;
                        break;
                    }
                }
                if(cnt==2){
                    flag2=0;
                    for(int i=3;i<=now;i++){
                        if(!ck(e[i].a,e[i].b,e[i].v,x2,y2)){
                            flag2=1;
                            break;
                        }
                    }
                }
                flag=flag1&flag2;
            }
            else {
                flag=1;
            }
         }
         else if(now==1){
            int up=sqrt(e[1].v+1),x=e[1].a,y=e[1].b,v=e[1].v,flags=1;
            for(int i=1;i<=up;i++){
                if(v%i==0){
                    int z=v/i;
                    if(x<=i&&y<=z||y<=i&&x<=z) {
                        flags=0;
                        break;
                    }
                }
            }
            flag=flags;
         }
         printf("Case #%d: ",++cas);
         if(flag){
            printf("No\n");
         }
         else printf("Yes\n");
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_41955236/article/details/84403613