- 论坛徽章:
- 0
|
1.第一种做法,对每行或每列进行二分查找,则效率为R*log(C)或C*log(R)。
第二种想法,是不断地将查找范围向右上角缩小,具体做法见代码,也是采用了二分。
- #include <iostream>
- #include <cstdio>
- #include <cstring>
- using namespace std;
- int mat[1005][1005];
- int R,C,Q; //R表示行数,C表示列数,Q表示要查询的数
- int f(int x1,int y1,int x2,int y2){
- int l,r,m;
- if(x1==x2){
- l=y1,r=y2;
- while(l<=r){
- //printf("====%d\n",m);
- m=(l+r)>>1;
- if(Q>mat[x1][m])
- l=m+1;
- else if(Q<mat[x1][m])
- r=m-1;
- else return m;
- }
- }
- else {
- l=x1,r=x2;
- while(l<=r){
- //printf("++++%d\n",m);
- m=(l+r)>>1;
- if(Q>mat[m][y1])
- l=m+1;
- else if(Q<mat[m][y1])
- r=m-1;
- else return m;
- }
- }
- return l;
- }
- bool Find(int x1,int y1,int x2,int y2){
- int i,j;
- int flag=0;
- while(y1>=1 && y1<=C && x2>=1 && x2<=R && flag==0){
- printf("%d %d %d %d\n",x1,y1,x2,y2);
- if(x1==x2 || y1==y2)
- flag++;
- i=f(x2,y1,x2,y2);
- if(Q==mat[x2][i])
- return true;
- j=f(x1,y1,x2,y1);
- if(Q==mat[j][y1])
- return true;
- y1=i;
- x2=j-1;
- printf("%d %d %d %d\n",x1,y1,x2,y2);
- }
- return false;
- }
- int main(){
- freopen("in.txt","r",stdin);
- freopen("out.txt","w",stdout);
- while(~scanf("%d%d",&R,&C)){
- memset(mat,-1,sizeof(mat));
- int i,j;
- for(i=1;i<=R;i++){
- for(j=1;j<=C;j++){
- scanf("%d",&mat[i][j]);
- }
- }
- scanf("%d",&Q);
- if(Find(1,1,R,C)){
- puts("Found!");
- }
- else {
- puts("Not found!");
- }
- }
- }
复制代码 2.(1)其实就是一个菲波那契数列,可以用矩阵的快速乘法来得到一个log(N)的算法,具体见代码,但因为精度问题,只能算到N=91时的情况。
- #include <iostream>
- #include <cstdio>
- #include <cstring>
- using namespace std;
- typedef long long LL;
- struct Matrix{
- int r,c;
- LL mat[5][5];
- void init(int rr=0,int cc=0){
- r=rr,c=cc;
- memset(mat,0,sizeof(mat));
- }
- };
- void mul(Matrix &m1,Matrix &m2,Matrix &m3){
- Matrix temp;
- temp.init(m1.r,m2.c);
- for(int i=1;i<=m1.r;i++){
- for(int j=1;j<=m2.c;j++){
- for(int k=1;k<=m1.c;k++){
- if(m1.mat[i][k]>0 && m2.mat[k][j]>0){
- temp.mat[i][j]=temp.mat[i][j]+m1.mat[i][k]*m2.mat[k][j];
- }
- }
- }
- }
- m3.init(temp.r,temp.c);
- for(int i=1;i<=temp.r;i++){
- for(int j=1;j<=temp.c;j++){
- m3.mat[i][j]=temp.mat[i][j];
- }
- }
- }
- LL Work(Matrix &temp,Matrix &res,int N){
- N--;
- while(N){
- if(N & 1){
- mul(temp,res,res);
- }
- mul(temp,temp,temp);
- N>>=1;
- }
- return res.mat[2][1];
- }
- int main(){
- Matrix temp,res;
- int N=0;
-
- while(~scanf("%d",&N)){ //N<=91
- //init
- res.init(3,2);
- res.mat[1][1]=1,res.mat[2][1]=1;
- temp.init(3,3);
- temp.mat[1][1]=0,temp.mat[1][2]=1,temp.mat[2][1]=1,temp.mat[2][2]=1;
- //work
- printf("%d: %lld\n",N,Work(temp,res,N));
- }
- }
复制代码 (2).这个……应该就是2^(N-1) |
|