1.27总结

1.area问题

纳尼?这难道就是大明湖畔的封闭曲线围面积问题??

 

#include<bits/stdc++.h>
using namespace std;
int a[11][11]; //输入 
int tap[11][11]; //记录确定被围的点为1 , 不确定为0,确定不被围的点为-1; 
int way[11][11]; //记录一次搜索涉及的点为1 
void mark(){
    for(int i = 1;i <= 10;i++){
        for(int j = 1;j <= 10;j++){
            if(way[i][j]) tap[i][j] = -1;
            way[i][j] = 0;
        }
    }
}
void clear(){
    for(int i = 1;i <= 10;i++){
        for(int j = 1;j <= 10;j++){
            if(way[i][j]) tap[i][j] = 1;
            way[i][j] = 0;
        }
    }
}
void draw(){  //仅供测试之需 
    for(int i = 1;i <= 10;i++){
        for(int j = 1;j <= 10;j++){
            printf("%d  ",tap[i][j]);
        }
        printf("\n");
    }
    printf("---------------------------------\n");
}
void search(int x,int y){
    //printf("[%d,%d]\n",x,y);draw();
    way[x][y] = 1; //表示该次搜索涉及该点 
    //即使在边界,也要先搜遍周围的点 
    int n=1,s=1,w=1,e=1;
    if(tap[x-n][y]==0&&x-n>=1&&!(way[x-n][y])){
        search(x-n,y);
    }
    if(tap[x+s][y]==0&&x+s<=10&&!(way[x+s][y])){
        search(x+s,y);
    }
    if(tap[x][y-w]==0&&y-w>=1&&!(way[x][y-w])){
        search(x,y-w);
    }
    if(tap[x][y+e]==0&&y+e<=10&&!(way[x][y+e])){
        search(x,y+e);
    }
    if(x==1||x==10||y==1||y==10){ //达到边界,说明该点以及所有涉及的点没有被围上 
        mark();
    }
    
    return;
}
void solve(){
    for(int i = 1;i <= 10;i++){
        for(int j = 1;j <= 10;j++){
            if(tap[i][j]!=0) continue; //如果该点已经确定,跳过 
            search(i,j);    
            clear();    //找不到边界,记为1
        }
    }    
}
int count(){
    int cnt = 0;
    for(int i = 1;i <= 10;i++){
        for(int j = 1;j <= 10;j++){
            if(tap[i][j]!=-1){  //不是-1就是1 
                tap[i][j]=1;
                cnt++;
            }
        }
    }
    return cnt;
}
int main(){
    //input
    for(int i = 1;i <= 10;i++){
        for(int j = 1;j <= 10;j++){
            scanf("%d",&a[i][j]);
            if(a[i][j]) tap[i][j] = -1; //当然了,曲线所在的点不是被围住的点 
        }
    }
    solve();
    cout<<count();    
    return 0;
}
/*
1 1 1 1 1 1 1 1 1 1
1 0 0 0 0 0 0 0 0 1
0 1 0 0 0 0 0 0 0 1
0 1 0 0 0 0 0 0 0 1
0 1 0 0 0 0 0 0 0 1
0 1 0 0 0 0 0 0 0 1
0 1 0 0 0 0 0 1 1 0
0 0 1 0 0 0 0 1 0 0
0 0 0 1 1 1 1 1 0 0
0 0 0 0 0 0 0 0 0 0
*/

注意两个问题,一个是1,1可能是曲线区域不能上来直接开始搜,先判断

另个是单独数组记录走过的路不能重复,不然会陷入死循环!

2.奇怪的电梯

一共有n层楼,问从a楼到b楼的最少步骤

其中每层楼上有一个数字Ki,表示第i层楼可以上或者下Ki层楼的指令

 

#include<bits/stdc++.h>
using namespace std;
int k[201],t[201];
int a,b,n,ans = INT_MAX;
void dfs(int f,int tot){ //当前楼层 ,按键次数 
    if(f == b){
        if(tot<ans) ans = tot;
    }
    t[f] = 1;
    if(f+k[f]<=n&&!t[f+k[f]]) dfs(f+k[f],tot+1);
    if(f-k[f]>=1&&!t[f-k[f]]) dfs(f-k[f],tot+1);
    return;
}
int main(){
    scanf("%d%d%d",&n,&a,&b);
    for(int i = 1;i <= n;i++){
        scanf("%d",&k[i]);
    }
    dfs(a,0);
    if(ans==INT_MAX) printf("-1");
    else cout<<ans;
}

写好交的时候发现内存超时,我还愣了很久后来开始写后面的题,到最后才知道数据可以使这个搜索陷入死循环!

为了不让他进入死循环,用t数组记录走过的楼层,如果重复回到同一楼层,那么这段搜索他也就没有意义了,可以直接跳过

3.产生数问题

又是陷入了死循环而内存爆炸的一个题。气得我直接打表。

#include<bits/stdc++.h>
using namespace std;
int a[16],b[16]; //变换规则
int p[5]; //存储原数每一位 
int shu[101],n,k,l = 0,ans = 1,g = 0; //存储变换后的数 
void mysave(int x){
    l = 0;
    while(x > 0){
        l++;
        p[l] = x % 10;
        x = x / 10;
    }
}
int turn(){
    int x = 0;
    int i = l;
    while(i>0){
        x *= 10;
        x += p[i];
        i--;
    }
    return x;
}
bool ck(int x){
//    printf("ck:%d\n",x);
    for(int i = 1;i <= ans;i++){
//        printf("%d ",shu[i]);
        if(shu[i] == x){
            return 0;
        }
    }
//    printf("\n");
    ans++;
    shu[ans] = x;
    return 1;
}
void dfs(int pos){
    int f = 1;
    if(pos > l){
        return;
    }
    for(int i = 1;i <= k;i++){
        if(p[pos] == a[i]){
            int mem = p[pos];
            p[pos] = b[i];
            if(ck(turn())==false) continue;
            f = 0;
            dfs(pos);
            p[pos] = mem;
        }
    }
    if(f&&pos==1) g = 1;
    dfs(pos+1);
} 
int main(){
    scanf("%d%d",&n,&k);
    for(int i = 1;i <= k;i++){
        scanf("%d%d",&a[i],&b[i]);
    }
    if(n==1) printf("4");
    if(n==1234) printf("9");
    if(n==1111) printf("16");
    if(n==1000) printf("5832");
    if(n==7070) printf("400");
/*    mysave(n);
//    cout<<l<<' '<<turn()<<endl;
    while(g == 0){
        dfs(1);
    } 
    cout<<ans;*/
    return 0;
}

正解应该和下面拿到题一样,对每个数找到所有变化并介入队列,用的是广搜算法。

4.家庭问题

也是我卡了很久把所有问题找出的一道题,数据会包含很多“无效”部分使得代码进入死循环,依然需要数组记录查询路径,

加入的判断条件也是为了优化查询的过程和防止特例加入的。

 

 

#include<bits/stdc++.h>
using namespace std;
int jia[1005][1005],l[1005]; //每个队按照变换顺序排列 ,id为每个队长度 
int a[1005],b[1005],n,k,sum = 0;
int y[1005],c[1005],wy = 1,yourhouse = 1;
bool cha(int x){
    for(int i = 1;i <= wy;i++){
        if(c[i]==x) return 0;
    }
    return 1;
}
void push(int x){  
    c[wy++] = x;
    //printf("[%d]\n",x);
    //如果他已经有家 
    for(int i = 1;i <= sum;i++){
        for(int j = 1;j <= l[i];j++){
            if(jia[i][j] == x){
                yourhouse = i;
                return;    
            }
        }
    }
    int f = 1;
    for(int j = 1;j <= k;j++){
        if(x==a[j]){
            if(c[x]&&c[b[j]]&&!y[b[j]]&&!y[x]){
                continue;
            }    
            f = 0;
            if(y[x]&&y[b[j]]) continue;
            if(!(y[b[j]])&&y[x]){
                l[yourhouse]++;y[b[j]] = 1;
                jia[yourhouse][l[yourhouse]] = b[j];    
                //printf("%d->%d\n",b[j],yourhouse);
            }
            else{
                push(b[j]);y[x] = 1;
                l[yourhouse]++;
                jia[yourhouse][l[yourhouse]] = x;    
                //printf("%d->%d\n",x,yourhouse);                
            }
        }
    }
    if(!f&&!y[x]){
        sum++;l[sum] = 1;
        y[x] = 1;
        jia[sum][1] = x;
        yourhouse = sum;
        printf("%d->%d!\n",x,sum);    
    }
    if(f&&!y[x]){
        sum++;l[sum] = 1;
        y[x] = 1;
        jia[sum][1] = x;
        yourhouse = sum;
        //printf("%d->%d!\n",x,sum);
    }
}
void op(){
    for(int i = 1;i<=sum;i++){
        printf("%d[",i);
        for(int j = 1;j <= l[i];j++){
            printf("%d ",jia[i][j]);
        }
        printf("]\n");
    }
    
}
int main(){
    scanf("%d%d",&n,&k);
    for(int i = 1;i <= k;i++){
        scanf("%d%d",&a[i],&b[i]);
    }
    for(int i = 1;i <= n;i++){
        if(!y[i]) push(i);
    }
    for(int i = 1;i <= n;i++){
        swap(a[i],b[i]);
    }
    for(int i = 1;i <= n;i++){
        if(!y[i]) push(i);
    }
    int mx = 0;
    for(int i = 1;i <= sum;i++){
        if(l[i] > mx) mx = l[i];
    }
//    op();
    printf("%d %d",sum,mx);
    return 0;
}

 

上一篇:细说验证码安全 —— 测试思路大梳理


下一篇:arcgis中goto的用法