POJ topic training, initial stage and basic algorithm

Keywords: C Algorithm

Introduction

There's nothing to say. It's done. Feudal superstition belongs to yes

Knowledge points involved

Enumeration, violence, construction, simulation

subject

1753

Main idea of the title: omitted

Idea: I've done it before. The basic idea is search, but bitset should be used to optimize storage

code

#include <iostream>
#include <bitset>
#include <queue>
#include <cstdlib>
#include <cstdio>
using namespace std;
const int maxn=1e6+10;
typedef bitset<16> bit;
int Next[]= {0,1,-1,-4,4};
bool vis[maxn];
int main() {
    int ans=-1,cnt=0;
    bit t;
    for(int i=0; i<16; i++) {
        char ch;
        cin >>ch;
        t[i]=(ch=='b'?1:0);
    }
    queue<bit>q;
    q.push(t);
    while(!q.empty()) {
        int len=q.size();
        while(len--) {
            t=q.front();
            q.pop();
            if(t.count()==16||t.count()==0) {
                ans=cnt;
                break;
            }
            if(ans!=-1)break;
            if(vis[t.to_ulong()])continue;
            vis[t.to_ulong()]=1;
            for(int i=0; i<16; i++) {//It's better to think in one dimension, and it's easy to have problems in two dimensions
                bit tmp=t;
                int x=i/4,y=i%4;
                for(int j=0; j<5; j++) {
                    if(j<3&&(y+Next[j]<0||y+Next[j]>=4))
                        continue;
                    if(j>=3&&(i+Next[j]<0||i+Next[j]>=16))
                        continue;
                    tmp.flip(y+4*x+Next[j]);
                }
                q.push(tmp);
            }
        }
        if(ans!=-1)break;
        cnt++;
    }
    if(ans!=-1)printf("%d",ans);
    else printf("Impossible");
    return 0;
}

2965

It is similar to the previous question, but each time you turn the page, you change a row and a column

Idea: for a + position, if you want to completely change it, you need to turn over all the rows and columns centered on it for seven times. The other positions centered on it need to be turned over four times. The even times are the same as the initial, and the odd times are the same as the once. For each + position, you need to turn over once directly (operate the rows and columns at the same time), and the last position is 1, The number of 1 is the number to be turned

code

#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <bitset>
#include <queue>
using namespace std;
const int maxn=1e6+10;
int times[20],ans;
char ch;
int main() {
    for(int i=0; i<16; i++) {
        cin >>ch;
        if(ch=='+') {
            int row=i/4,col=i%4;
            for(int j=0; j<4; j++)
                times[row*4+j]^=1;
            for(int j=0; j<4; j++)
                times[col+j*4]^=1;
            times[i]^=1;
        }
    }
    for(int i=0; i<16; i++)
        if(times[i])ans++;
    cout <<ans<<endl;
    for(int i=0; i<16; i++)if(times[i])cout <<i/4+1<<" "<<i%4+1<<endl;
    return 0;
}

1328

Main idea of the topic: a Cartesian coordinate system is given. The positive half axis of y is the sea, and the negative half axis of y is the shore. There are some islands (regarded as points) on the sea. The horizontal and vertical coordinates of each island are given. Now some radars are to be built on the x axis, and the radiation radius of the radar is given. It is required that at least several radars can realize the full coverage of the islands

Idea: at first, I thought it was a geometric problem. In fact, it was a greedy classical interval problem. It was wonderful.
For each point, there are at least two points on the x-axis whose distance from the point is the radius, that is, the desirable coordinate range of the point within the radius is an interval. Then find its interval for each point and sort it from left to right. The problem is transformed into giving multiple intersectable intervals. At least several points need to be placed to make each interval at least one point

code

#include <iostream>
#include <algorithm>
#include <cstdlib>
#include <cstdio>
#include <cmath>
using namespace std;
int n,d,k;
struct node {
    double ll,rr;
    bool operator<(const node t)const {//heavy load
        return rr<t.rr;
    }
} e[1212];
int main() {
    while(~scanf("%d%d",&n,&d)&&n&&d) {
        int ans=0;
        double rad=d,r;
        for(int i=0; i<n; i++) {
            double x,y;
            scanf("%lf%lf",&x,&y);
            if(y>rad)ans=-0x3f3f3f3f;
            e[i].ll=x-sqrt(rad*rad-y*y);
            e[i].rr=x+sqrt(rad*rad-y*y);
        }
        sort(e,e+n);
        r=e[0].rr;
        ans++;
        for(int i=1; i<n; i++) {
            if(e[i].ll>r) {
                ans++;
                r=e[i].rr;
            } else if(e[i].rr<r)r=e[i].rr;
        }
        printf("Case %d: %d\n",++k,ans<0?-1:ans);
    }
    return 0;
}

2109

Enter two integers n,p, 1 ≤ p ≤ 1 0 101 1\le p\le 10^{101} 1 ≤ p ≤ 10101, find an integer k such that k n = p k^n=p kn=p

Idea: it can be solved directly, and the range of double can reach 300 bits

code

#include <iostream>
#include <cmath>
#include <cstdlib>
#include <cstdio>
using namespace std;
int main() {
    double n,p;
    while(~scanf("%lf%lf",&n,&p))
        printf("%.0f\n",pow(p,1.0/n));
    return 0;
}

2586

The profit and loss data of the company is lost, but the monthly profit and loss is a fixed integer, either profit s or loss d. the company has a profit and loss statement every five months, and the profit and loss of each statement is loss. There are eight such statements in a year, giving s and d. now it is necessary to determine the maximum profit of the company in the whole year when each statement is loss, If it exists, the maximum value is output, otherwise "resist" is output

Idea: concentrate the profits at the head of the interval, and the whole interval can be divided into such blocks: x x x x x , x x x x x , x x xxxxx,xxxxx,xx xxxxx,xxxxx,xx, discussion by situation, profit 10, loss 2, profit 8, loss 4, profit 6, loss 6, profit 3, loss 9, calculation results respectively

code

#include <iostream>
#include <cstdlib>
#include <cstdio>
using namespace std;
int s,d;
int main() {
    while(~scanf("%d%d",&s,&d)) {
        int ans=0;
        if(d>4*s)ans=10*s-2*d;
        else if(2*d>3*s)ans=8*s-4*d;
        else if(3*d>2*s)ans=6*s-6*d;
        else if(4*d>s)ans=3*s-9*d;
        else ans=-1;
        if(ans<0)printf("Deficit\n");
        else printf("%d\n",ans);
    }
    return 0;
}

3295

Main idea: input by p , q , r , s , t , K , A , N , C , E p,q,r,s,t,K,A,N,C,E p. A logical expression composed of Q, R, s, t, K, a, N, C and E. lowercase letters are variables and uppercase letters are operations. Give an operation table and ask whether the logical expression is eternal truth

Idea: use the stack simulation operation to violently traverse the values of all variables. Since the data range is not very large, it can be realized

code

#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cmath>
#include <queue>
#include <cstring>
#include <bitset>
#include <stack>
using namespace std;
bool K[2][2]= {0,0,0,1},A[2][2]= {0,1,1,1},C[2][2]= {1,1,0,1},E[2][2]= {1,0,0,1};
char str[121];
int main() {
    while(~scanf("%s",str)&&str[0]!='0') {
        int len=strlen(str);
        bool flag=0;
        for(int p=0; p<=1; p++) {
            for(int q=0; q<=1; q++) {
                for(int r=0; r<=1; r++) {
                    for(int s=0; s<=1; s++) {
                        for(int t=0; t<=1; t++) {
                            stack<int>S;
                            for(int i=len-1; i>=0; i--) {
                                bool x=0,y=0;
                                switch(str[i]) {
                                case 'p':
                                    S.push(p);
                                    break;
                                case 'q':
                                    S.push(q);
                                    break;
                                case 'r':
                                    S.push(r);
                                    break;
                                case 's':
                                    S.push(s);
                                    break;
                                case 't':
                                    S.push(t);
                                    break;
                                case 'K':
                                    x=S.top();
                                    S.pop();
                                    y=S.top();
                                    S.pop();
                                    S.push(K[y][x]);
                                    break;
                                case 'A':
                                    x=S.top();
                                    S.pop();
                                    y=S.top();
                                    S.pop();
                                    S.push(A[y][x]);
                                    break;
                                case 'N':
                                    x=S.top();
                                    S.pop();
                                    S.push(!x);
                                    break;
                                case 'C':
                                    x=S.top();
                                    S.pop();
                                    y=S.top();
                                    S.pop();
                                    S.push(C[y][x]);
                                    break;
                                case 'E':
                                    x=S.top();
                                    S.pop();
                                    y=S.top();
                                    S.pop();
                                    S.push(E[y][x]);
                                    break;
                                }
                            }
                            if(!S.top()) {
                                printf("not\n");
                                flag=1;
                                break;
                            }
                        }
                        if(flag)break;
                    }
                    if(flag)break;
                }
                if(flag)break;
            }
            if(flag)break;
        }
        if(!flag)
            printf("tautology\n");
    }

    return 0;
}

1068

Main idea of the title: omitted

Idea: it was complicated by the data range at that time. In fact, it would be good to simulate directly. First construct the original string, and then count according to the rules of W

code

#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cmath>
#include <queue>
#include <cstring>
#include <bitset>
#include <stack>
using namespace std;
int t,n,a[121]= {0};
int main() {
    scanf("%d",&t);
    while(t--) {
        scanf("%d",&n);
        int str[50]= {0};
        int j,i,k,ans=0;
        for(i=1; i<=n; i++)
            scanf("%d",a+i);
        for(j=0,i=1; i<=n; i++)//Change P to 01, 0 on the left and 1 on the right
            for( k=0;; k++)
                if(k<a[i]-a[i-1])j++;//Find the right position
                else if(k==a[i]-a[i-1]) {//No change, right
                    str[j++]=1;
                    break;
                }
        int len=j;
        for(int i=0; i<len; i++)//str to W
            if(str[i]) {//Find the nearest 0 by backtracking when encountering 1
                ans=2;
                for(int j=i-1;; j--)
                    if(str[j]==0) {
                        str[i]=str[j]=10000;//Empty after use
                        break;
                    } else
                        ans++;//Record the number of matches
                printf("%d ",ans/2);
            }
        putchar('\n');
    }
    return 0;
}

2632

Main idea of the title: omitted

Idea: direct simulation is enough, but note that the coordinates are opposite, and a set of data should be processed at one time

code

#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <map>
using namespace std;
const int maxn=1e5+10;
int k,a,b,n,m,Next[4][2]= {0,1,1,0,0,-1,-1,0};
struct node {
    int x,y,d;
} r[121];
int vis[121][121];
char ch;
map<char,int>w;
int main() {
    cin >>k;
    w['E']=0;
    w['N']=1;
    w['W']=2;
    w['S']=3;
    while(k--) {
        cin >>a>>b>>n>>m;
        memset(vis,0,sizeof(vis));
        for(int i=1; i<=n; i++) {
            cin >>r[i].y>>r[i].x>>ch;
            r[i].d=w[ch];
            vis[r[i].x][r[i].y]=i;
        }
        bool flag=0;
        int id=0,rob2=0;
        while(m--) {
            int i,c;
            char j;
            cin >>i>>j>>c;
            if(!flag) {
                while(c--) {
                    if(j=='L')r[i].d=(r[i].d+1)%4;
                    if(j=='R')r[i].d=(r[i].d+3)%4;
                    if(j=='F') {
                        int xx=r[i].x+Next[r[i].d][0],yy=r[i].y+Next[r[i].d][1];
                        if(xx<1||xx>b||yy<1||yy>a) {
                            id=i;
                            flag=1;
                            continue;
                        } else if(vis[xx][yy]) {
                            id=i;
                            rob2=vis[xx][yy];
                            flag=1;
                            continue;
                        } else {
                            vis[r[i].x][r[i].y]=0;
                            r[i].x=xx;
                            r[i].y=yy;
                            vis[xx][yy]=i;
                        }
                    }
                }
            }
        }
        if(flag) {
            if(id&&rob2)
                cout <<"Robot "<<id<<" crashes into robot "<<rob2<<endl;
            else
                cout<<"Robot "<<id<<" crashes into the wall"<<endl;
        } else
            cout <<"OK"<<endl;
    }
    return 0;
}

1573

Main idea of the title: omitted

Idea: simple simulation, according to the meaning of the topic, pay attention to judge the number of steps to take when there is a ring

code

#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
using namespace std;
int n,m,s,ans=0,loop=0;
int vis[20][20];
char maze[20][20];
bool DFS(int x,int y) {
    if(x<1||x>n||y<1||y>m)return 1;
    if(vis[x][y]) {
        loop=ans-vis[x][y]+1;
        ans=vis[x][y]-1;
        return 0;
    }
    vis[x][y]=++ans;
    switch(maze[x][y]) {
    case 'N':
        return DFS(x-1,y);
        break;
    case 'S':
        return DFS(x+1,y);
        break;
    case 'E':
        return DFS(x,y+1);
        break;
    case 'W':
        return DFS(x,y-1);
        break;
    }
}
int main() {
    while(~scanf("%d%d%d",&n,&m,&s)&&n&&m&&s) {
        ans=loop=0;
        for(int i=1; i<=n; i++)
            scanf("%s",maze[i]+1);
        if(DFS(1,s))
            printf("%d step(s) to exit\n",ans);
        else
            printf("%d step(s) before a loop of %d step(s)\n",ans,loop);
        memset(vis,0,sizeof(vis));
    }
    return 0;
}

2993

Main idea of the title: the inverse of 2996 gives the coordinates to find the chessboard

Idea: input and output are disgusting... Just simulate directly

code

#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <cstring>
using namespace std;
char maze[100][100];
char l[50]="+---+---+---+---+---+---+---+---+",h[50]="|:::|...|:::|...|:::|...|:::|...|",m[50]="|...|:::|...|:::|...|:::|...|:::|";
int main() {
    for(int i=1; i<=17; i+=2)
        memcpy(maze[i]+1,l,sizeof(l));
    for(int i=2; i<=16; i+=4)
        memcpy(maze[i]+1,m,sizeof(m));
    for(int i=4; i<=16; i+=4)
        memcpy(maze[i]+1,h,sizeof(h));
    char str1[100]= {'\0'},str2[100]= {'\0'};
    scanf("%s %s",str1,str2);
    for(int i=0; str2[i];) {
        if(str2[i]==',') {
            i++;
            continue;
        }
        if(isupper(str2[i])) {
            int x=str2[i+1]-'a'+1,y=str2[i+2]-'0';
            maze[2*(8-y+1)][4*x-1]=str2[i];
            i+=3;
        } else {
            int x=str2[i]-'a'+1,y=str2[i+1]-'0';
            maze[2*(8-y+1)][4*x-1]='P';
            i+=2;
        }
    }
    scanf("%s %s",str1,str2);
    for(int i=0; str2[i];) {
        if(str2[i]==',') {
            i++;
            continue;
        }
        if(isupper(str2[i])) {
            int x=str2[i+1]-'a'+1,y=str2[i+2]-'0';
            maze[2*(8-y+1)][4*x-1]=tolower(str2[i]);
            i+=3;
        } else {
            int x=str2[i]-'a'+1,y=str2[i+1]-'0';
            maze[2*(8-y+1)][4*x-1]='p';
            i+=2;
        }
    }
    for(int i=1; i<=17; i++)
        printf("%s\n",maze[i]+1);
    return 0;
}

2996

Give a chess board and output the coordinates of each piece according to the rules

Idea: direct simulation is enough. Pay attention when outputting. Black is from top to bottom and white is from bottom to top

code

#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <queue>
#include <stack>
using namespace std;
struct node {
    char x;
    int y;
};
queue<node>white[10],black[10];
int pos[]= {0,3,7,11,15,19,23,27,31};
char maze[200][200],w[]="#KQRBNP";
int main() {
    for(int i=1; i<=17; i++) {
        scanf("%s",maze[i]+1);
        getchar();
    }
    for(int i=16; i>=2; i-=2)
        for(int j=1; j<=8; j++)
            switch(maze[i][pos[j]]) {
            case 'K':
                white[1].push({j+'a'-1,8-i/2+1});
                break;
            case 'Q':
                white[2].push({j+'a'-1,8-i/2+1});
                break;
            case 'R':
                white[3].push({j+'a'-1,8-i/2+1});
                break;
            case 'B':
                white[4].push({j+'a'-1,8-i/2+1});
                break;
            case 'N':
                white[5].push({j+'a'-1,8-i/2+1});
                break;
            case 'P':
                white[6].push({j+'a'-1,8-i/2+1});
                break;
            }
    bool flag=0;
    printf("White: ");
    for(int i=1; i<=5; i++)
        while(!white[i].empty()) {
            if(!flag)flag=1;
            else printf(",");
            node t=white[i].front();
            white[i].pop();
            printf("%c%c%d",w[i],t.x,t.y);
        }
    while(!white[6].empty()) {
        if(!flag)flag=1;
        else printf(",");
        node t=white[6].front();
        white[6].pop();
        printf("%c%d",t.x,t.y);
    }
    for(int i=2; i<=16; i+=2)
        for(int j=1; j<=8; j++)
            switch(maze[i][pos[j]]) {
            case 'k':
                black[1].push({j+'a'-1,8-i/2+1});
                break;
            case 'q':
                black[2].push({j+'a'-1,8-i/2+1});
                break;
            case 'r':
                black[3].push({j+'a'-1,8-i/2+1});
                break;
            case 'b':
                black[4].push({j+'a'-1,8-i/2+1});
                break;
            case 'n':
                black[5].push({j+'a'-1,8-i/2+1});
                break;
            case 'p':
                black[6].push({j+'a'-1,8-i/2+1});
                break;
            }
    flag=0;
    putchar('\n');
    printf("Black: ");
    for(int i=1; i<=5; i++)
        while(!black[i].empty()) {
            if(!flag)flag=1;
            else printf(",");
            node t=black[i].front();
            black[i].pop();
            printf("%c%c%d",w[i],t.x,t.y);
        }
    while(!black[6].empty()) {
        if(!flag)flag=1;
        else printf(",");
        node t=black[6].front();
        black[6].pop();
        printf("%c%d",t.x,t.y);
    }
    return 0;
}

reference

  1. Y2K Accounting Bug POJ2586
  2. POJ1328-Radar Installation
  3. poj2632
  4. POJ2965 The Pilots Brothers' refrigerator
  5. Enumeration solution and efficient solution of POJ2965

Posted by able on Wed, 13 Oct 2021 20:54:50 -0700