UVA Multiplication Table

来源:互联网 发布:c 高级编程 pdf 中文 编辑:程序博客网 时间:2024/05/16 19:19

                                Multiplication Table

题目链接
这道题是纯思路题+暴力模拟
分情况比较多,所以也不是很好写
1.如果全是问号,那么一定可以
2.如果有一个数,那么要判断这一个数是否符合条件,或者说这个数可能在这个位置吗
   比如样例
    ?????2 ?
    ???????
  在上面样例中,2明显不可能在那么靠后的位置
  但是如何判断???
   就一个一个假设,假设唯一的一个数为第i行(或者第i列的)
   这样可以算出来这个数是这一行(列)的第几个数,判断一下,如果这个数为第2个数,但是前面有5个问号,那么
  这个数的位置肯定是不正确的
3.如果有n个数(n>=2)
  那么我们可以先判断一下第一个数是否合法,如果第一个数合法,那么分别判断一下后面的数是否合法


还有个问题就是,如何假设这个数是第几行,或者第几列??
 如果n%2==0那么表示n可能为第2行的,所以我们需要暴力一点把所有情况全部暴力出来!!!

这道题很有可能超时,非常极限的过了,主要用了cin输入,如果scanf输入是稳过的,如果过不了就用scanf吧
#include<bits/stdc++.h>  #define MAX 1000  using namespace std;  struct node  {      int x;  //x,y记录坐标,V记录数值    int y;      int v;  }arr[MAX*MAX +5];  int x,y,sum;  bool work()  {      for(int i=1;i*i<=arr[1].v;i++)      {          int flag=1;          if(arr[1].v%i==0)//如果第一个数可以整除i,表示i可能表示第一个数在第i行 (纵向判断)         {              if(i>=arr[1].x&&arr[1].v/i>=arr[1].y)  //判断第一个数是否合法,第一个条件保证在第i行,第一个数合法            {                  for(int j=2;j<=sum;j++) //判断剩下的数是否符合条件                 {                      if((i+arr[j].x-arr[1].x)*(arr[1].v/i+arr[j].y-arr[1].y)!=arr[j].v)                      {                          flag=0;                      }                      if(!flag)                          break;                  }                  if(flag)                      return true;              }              if(arr[1].v/i>=arr[1].x&&i>=arr[1].y) //如果第一个数可以整除i,表示i可能表示第一个数在第i列(横向判断)             {                   flag=1;                      for(int j=2;j<=sum;j++)                      {                          if((arr[1].v/i+arr[j].x-arr[1].x)*(i+arr[j].y-arr[1].y)!=arr[j].v)                          {                              flag=0;                          }                          if(!flag)                              break;                      }                      if(flag)                          return true;              }          }      }      return false;  }  int main()  {      int t,now,case1=1;      cin>>t;      string str;      while(t--)      {          cin>>x>>y;          sum=0;          for(int i=1;i<=x;i++)          {              for(int j=1;j<=y;j++)              {                  cin>>str;                  if(str!="?")                  {                      now=0;                      for(int k=0;k<str.size();k++)                      {                          now=now*10+str[k]-'0';                      }                      arr[++sum].x=i;                      arr[sum].y=j;                      arr[sum].v=now;                  }              }          }          printf("Case #%d: ",case1++);          if(!sum)          {              cout<<"Yes"<<endl;          }          else if(sum==1)//如果只有一个数字          {              int flag=0;              for(int i=1;i<=sqrt(arr[1].v);i++)              {                  if(arr[1].v%i==0)                  {                      if(i>=arr[1].x&&arr[1].v/i>=arr[1].y)                      {                          flag=1;                      }                      else if(i>=arr[1].y&&arr[1].v/i>=arr[1].x)                      {                          flag=1;                      }                    }              }              if(flag)                  cout<<"Yes"<<endl;              else                  cout<<"No"<<endl;          }          else //如果有1个以上的数字         {              if(work())              {                  cout<<"Yes"<<endl;              }              else                  cout<<"No"<<endl;          }      }      return 0;  }  



原创粉丝点击