这题是剑指Offer一书中得题,但是实在感觉这题不用算法,既然知道了要查找的t,何不在输入的时候就进行比较,没必要开个二位数组再存,然后再查,也不过是增加时间而已,但是这题本来要表达的应该就是已知一个二维数组,求查找数组里的值,但仅仅是从Acmer角度来说,仅从A题的角度来说,输入后即可获取值,因为见到此题是在一个就读OJ平台上。但是不得不提的一点就是cin与scanf,第一遍用cin超时了。
不合规矩的做法:
#include <stdio.h>
int main()
{
int m,n,t,temp;
bool flag;
//freopen("/Users/sanyinchen/Workspaces/oc/conse/B_ali/B_ali/in.txt","r",stdin);
while(scanf("%d %d",&m,&n)!=EOF)
{
scanf("%d",&t);
flag=false;
for(int i=0;i<m;i++)
{
for(int j=0;j<n;j++)
{
scanf("%d",&temp);
if(temp==t)
{
flag=true;
// break;
}
}
//if(flag)break;
}
if(flag)
//cout<<"Yes"<<endl;
printf("Yes\n");
else
printf("No\n");
// cout<<"No"<<endl;
}
return 0;
}
使用二分的方法:
#include <stdio.h>
int a[1001][1001];
int main()
{
int m,n,t,low,high,mid;
bool flag;
//freopen("/Users/sanyinchen/Workspaces/oc/conse/B_ali/B_ali/in.txt","r",stdin);
while(scanf("%d %da",&m,&n)!=EOF)
{
scanf("%d",&t);
flag=false;
for(int i=0;i<m;i++)
for(int j=0;j<n;j++)
scanf("%d",&a[i][j]);
low=0;
high=m*n-1;
while(low<=high)
{
mid=(low+high)/2;
if(a[mid/n][mid%n]==t)
{
flag=true;
break;
}
if(a[mid/n][mid%n]<t)
{
low=mid+1;
}
else
{
high=mid-1;
}
}
if(flag)
printf("Yes\n");
else
printf("No\n");
}
return 0;
}
/**************************************************************
Problem: 1384
User: sanyinchen
Language: C++
Result: Accepted
Time:660 ms
Memory:4936 kb
****************************************************************/
其实上面的解法是错误的,上面的二分虽然可以通过九度的OJ平台,是因为提供的数据存在缺陷
比如书中给出的这样一组
4 4
7
1 2 8 9
2 4 9 12
4 7 10 13
6 8 11 15
这样一组就无法满足二分,当然可以试用一遍快排使其有序,但如果那样做的话还不如直接构建二叉搜索树,但是要构建二叉搜索树需要遍历每一个元素,既然能遍历每一个元素,为何不在遍历时找出元素。
书中给出的方法是这样的,举个例子,比如是寻找7这个元素,从右上角开始,9>7,9又为当前列最小的数,因此这一列都大于7是一个必然事件。删去此列,接着寻找右上角元素:8。同理删去这一列。右上角元素为2。此时2<7。因为此时2为此行最大值,因为,8,9所在列已经被排除,因此可以确定此行肯定都小于7,删去此行。同理删去4这一行。寻找右上角元素:7即为查找的元素,退出循环。
初始条件 col=0;row=n-1;判断条件:col<m&&row>=0;
#include <stdio.h>
int a[1001][1001];
int main()
{
int m,n,t,col,row;
bool flag;
// freopen("/Users/sanyinchen/Workspaces/oc/conse/B_ali/B_ali/in.txt","r",stdin);
while(scanf("%d %da",&m,&n)!=EOF)
{
scanf("%d",&t);
flag=false;
for(int i=0;i<m;i++)
for(int j=0;j<n;j++)
scanf("%d",&a[i][j]);
col=0;
row=n-1;
while(col<m&&row>=0)
{
if(a[col][row]==t)
{
flag=true;
break;
}
if(a[col][row]>t)
{
row--;
}
else
{
col++;
}
}
if(flag)
printf("Yes\n");
else
printf("No\n");
}
return 0;
}