紫薯 第四章习题enmmmm

习题4-1 象棋uva1589

 题意,输入帅  马 车 炮 将 的棋盘位置,保证局面合法且红方已经将军判断红方是否能将黑方将死

 做法 强行一波 模拟 ,把 将 和 车 看成一样的, 10*9的棋盘而已,两个字符数组 一个是旗子位置 另一个是红方可以走的位置

 黑方的 将 如果上下左右 能走的地方都是被标记过的(红方可以走的)  则GG

 有个 需要注意的地方 就是炮 和 车 在列举可能情况的时候,先赋值 再判断是否循环结束

 比如说车隔着前面四个格子是马 马位置也要赋值 因为可能 对面的将下一步把马给吃掉了  //因为这个一直WA 心塞

#include <cstdio>//是否能将死 对面的shuai 
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;

char kaiju[11][11],maybe[11][11],ch;
int n,x,y,x2,y2,a,t1,t2;
void RHG(int x1,int y1) {
    
    for(int i = x1-1; i > 0; i--) 
    { 
        maybe[i][y1] = 'B';//因为可能旗子会被帅吃掉
        if(kaiju[i][y1] != 'A' && kaiju[i][y1] != 'S') 
            break;
    }
    for(int i = x1+1; i < 4; i++) 
    {
         maybe[i][y1] = 'B';
         if(kaiju[i][y1] != 'A' && kaiju[i][y1] != 'S') 
             break;
    }
    for(int i = y1+1; i < 7; i++) 
    {
         maybe[x1][i] = 'B';
         if(kaiju[x1][i] != 'A' && kaiju[x1][i] != 'S')
              break;
    }
    for(int i = y1-1; i > 3; i--) 
    {
         maybe[x1][i] = 'B';
         if(kaiju[x1][i] != 'A' && kaiju[x1][i] != 'S') 
             break;
    }
    return;
}

void RH(int x1,int y1) {
    if (kaiju[x1-1][y1]=='A' && x1-2>0 && y1+1<7) maybe[x1-2][y1+1] = 'B';
    if (kaiju[x1-1][y1]=='A' && x1-2>0 && y1-1>3) maybe[x1-2][y1-1] = 'B';

    if (kaiju[x1+1][y1]=='A' && x1+2<4 && y1+1<7) maybe[x1+2][y1+1] = 'B';
    if (kaiju[x1+1][y1]=='A' && x1+2<4 && y1-1>3) maybe[x1+2][y1-1] = 'B';

    if (kaiju[x1][y1-1]=='A' && y1-2>3 && x1-1>0) maybe[x1-1][y1-2] = 'B';
    if (kaiju[x1][y1-1]=='A' && y1-2>3 && x1+1<4) maybe[x1+1][y1-2] = 'B';

    if (kaiju[x1][y1+1]=='A' && y1+2<7 && x1-1>0) maybe[x1-1][y1+2] = 'B';
    if (kaiju[x1][y1+1]=='A' && y1+2<7 && x1+1<4) maybe[x1+1][y1+2] = 'B';
}
void RC(int x1,int y1) {
    if (x1==1 && y1<7 && y1>3 && kaiju[2][y1]!='S' 
        && kaiju[2][y1]!='A')
        maybe[3][y1] = 'B';
    int j;
    for (j = x1-1; j > 0; j--)
    {
        if (kaiju[j][y1] == 'S' )    return;
        if (kaiju[j][y1] != 'A')    break;
    }for (int i = j-1; i > 0; i--) {
        maybe[i][y1] = 'B';
        if (kaiju[i][y1] != 'A' && kaiju[i][y1] != 'S')  break;        
    }

    for (j = y1-1; j >3; j--)
    {
        if (kaiju[x1][j] == 'S')    return;
        if (kaiju[x1][j] != 'A')    break;
    }for (int i = j-1; i > 3; i--) {
            maybe[x1][i] = 'B';
        if (kaiju[x1][i] == 'A' && kaiju[x1][i] != 'S') break;
    }

    for( j = y1+1; j < 7; j++)
    {
        if (kaiju[x1][j] == 'S')    return;
        if (kaiju[x1][j] != 'A')    break;
    }for (int i = j+1; i < 7; i++) {
        maybe[x1][i] = 'B';
        if (kaiju[x1][i] == 'A' && kaiju[x1][i]) break;
    }
}
int jiang() {//s[x][y]== G
    if (x-1>0 && maybe[x-1][y]=='A')return 0;
    if (x+1<4 && maybe[x+1][y]=='A')return 0;
    if (y-1>3 && maybe[x][y-1]=='A')return 0;
    if (y+1<7 && maybe[x][y+1]=='A')return 0;
    return 1;
}

int main() {
    
    while (scanf("%d%d%d",&n,&x,&y) == 3 && n) {
        int v[8][3];
        memset(maybe,'A',sizeof(maybe));
        memset(kaiju,'A',sizeof(kaiju));
        memset(v,0,sizeof(v));
        
        kaiju[x][y] = 'S';
        
        for (int i = 0; i < n; i++)
        {
            char s[33];
            scanf("%s%d%d", s, &x2, &y2);
            //printf("%s\n", s);
            ch = s[0];
            v[i][0] = x2;v[i][1] = y2;
            kaiju[x2][y2] = ch;
            getchar();
        }

        for (int i = 0; i < n; i++) {
            int x1 = v[i][0],y1 = v[i][1];
            if (kaiju[x1][y1] == 'G' || kaiju[x1][y1] =='R') RHG(x1,y1);
            if (kaiju[x1][y1] == 'H')    RH(x1,y1);
            if (kaiju[x1][y1] == 'C')    RC(x1,y1);
        }
        puts(jiang()?"YES":"NO");
        //if (jiang()) printf("YES\n");  //GG 无路可退
        //else  printf("NO\n");
        
    }
    
    return 0;
}
View Code

 看到别人有个玄学的做法 没看懂2333 而且很短

#include <cstdio>
#define RD(X) if(s[X].x||s[X].y)s[X+1].x=x,s[X+1].y=y;else s[X].x=x,s[X].y=y
#define CHECKR(X) (check(s[X],m,n)&&!between(s[X],m,n))
#define CHECKC(X) (check(s[X],m,n)&&between(s[X],m,n)==1)
char c;
int x,y,N;
struct point{int x,y;};
point s[8];//B,G,R1,R2,H1,H2,C1,C2
int mx[4]={1,-1,0,0},my[4]={0,0,1,-1};
int abs(int tt){return ((tt<0)?-tt:tt);}
int mid(int a1,int a2,int a3){return ((a1<a2&&a2<a3)||(a1>a2&&a2>a3));}
int check(point TT,int x2,int y2){return ((TT.x==x2&&TT.y!=y2)||(TT.y==y2&&TT.x!=x2));}
int between(point T,int x2,int y2){
    int xx=0;
    for(int i=1;i<8;i++)
        xx+=(mid(T.x,s[i].x,x2)&&check(s[i],x2,y2))+(mid(T.y,s[i].y,y2)&&check(s[i],x2,y2));
    return xx;
}
int checkH(point _T,int mm,int nn){
    int dm=_T.x-mm,dn=_T.y-nn,am=abs(dm),an=abs(dn);
    return (am+an==3&&am&&an&&!between(_T,_T.x-(int(dm/2)<<1),_T.y-(int(dn/2)<<1)));
}
int Try(int m,int n){
    if(m<1||m>3||n<4||n>6||\
    (n==s[1].y&&!between(s[1],m,n))||\
    CHECKR(2)||CHECKR(3)||\
    CHECKC(6)||CHECKC(7))return 0;
    return !(checkH(s[4],m,n)||checkH(s[5],m,n));
}
int main(){
    while(~scanf("%d%d%d",&N,&s[0].x,&s[0].y)&&(N||s[0].x||s[0].y)){
        for(int i=1;i<8;i++)s[i].x=s[i].y=0;
        while(N--){
            scanf(" %c%d%d",&c,&x,&y);
            if(c=='G')s[1].x=x,s[1].y=y;
            if(c=='R')RD(2);
            if(c=='H')RD(4);
            if(c=='C')RD(6);
        }
        for(int i=0;i<4;i++)
            if(Try(s[0].x+mx[i],s[0].y+my[i])){printf("NO\n");goto lable;}
        printf("YES\n");lable:;
    }
    return 0;
}
View Code

 

习题4-2 正方形 uva201

 题意 输入n行n列的小黑点,输入m条边,问能组成的正方形个数

 解法:遍历所有点,先判断右 下边有无边相连,再右下 右下左 有无边 (从 1-> 9),always WA ,不知为何

#include<algorithm>
#include<cstring>
#include<cstdio>
#include<cmath>
int n,m,v[20][20],h[20][20],a[11];
using namespace std;

void panduan(int x,int y) {
    if(v[x][y] && h[x][y]) //
    {
        //printf(" a[1] pandusan\n");
        if(v[x][y+1] 
        && h[x+1][y])  a[1]++;
        
        if(v[x+1][y] && h[x][y+1])
        {
            if(v[x][y+2] && v[x+1][y+2] 
            && h[x+2][y] && h[x+2][y+1]) a[2]++;
                
            if(v[x+2][y] && h[x][y+2])
            {
                //printf(" a[3] pandusan\n");
                if(v[x][y+3] && v[x+1][y+3] && v[x+2][y+3] 
                && h[x+3][y] && h[x+3][y+1] && h[x+3][y+2]) a[3]++;

                if(v[x+3][y] && h[x][y+3])
                {
                //    printf(" a[4] pandusan\n");
                    if(v[x][y+4] && v[x+1][y+4] && v[x+2][y+4] && v[x+3][y+4]
                    && h[x+4][y] && v[x+4][y+1] && v[x+4][y+2] && v[x+4][y+3]) a[4]++;

                    if(v[x+4][y] && h[x][y+4])
                    {
                //        printf(" a[5] pandusan\n");
                        if(v[x][y+5] && v[x+1][y+5] && v[x+2][y+5] && v[x+3][y+5] && v[x+4][y+5]
                        && h[x+5][y] && h[x+5][y+1] && h[x+5][y+2] && h[x+5][y+3] && h[x+5][y+4]) a[5]++;

                        if(v[x+5][y] && h[x][y+5])    
                        {
                            if(v[x][y+6] && v[x+1][y+6] && v[x+2][y+6] && v[x+3][y+6] && v[x+4][y+6] && v[x+5][y+6]
                            && h[x+6][y] && h[x+6][y+1] && h[x+6][y+2] && h[x+6][y+3] && h[x+6][y+4] && h[x+6][y+5]) a[6]++;

                            if(v[x+6][y] && h[x][y+6])    
                            {
                                if(v[x][y+7] && v[x+1][y+7] && v[x+2][y+7] && v[x+3][y+7] && v[x+4][y+7] && v[x+5][y+7] && v[x+6][y+7]
                                && h[x+7][y] && h[x+7][y+1] && h[x+7][y+2] && h[x+7][y+3] && h[x+7][y+4] && h[x+7][y+5] && h[x+7][y+6]) a[7]++;

                                if(v[x+7][y] && h[x][y+7])
                                {
                                    if(v[x][y+8] && v[x+1][y+8] && v[x+2][y+8] && v[x+3][y+8] && v[x+8][y+8] && v[x+5][y+8] && v[x+6][y+8] && v[x+7][y+8]
                                    && h[x+8][y] && h[x+8][y+1] && h[x+8][y+2] && h[x+8][y+3] && h[x+8][y+4] && h[x+8][y+5] && h[x+8][y+6] && h[x+8][y+7]) a[8]++;

                                    if(v[x+8][y] && h[x][y+8])
                                    {
                                        if(v[x][y+9] && v[x+1][y+9] && v[x+2][y+9] && v[x+3][y+9] && v[x+4][y+9] && v[x+5][y+9] && v[x+6][y+9] && v[x+7][y+9] && v[x+8][y+9]
                                        && h[x+9][y] && h[x+9][y+1] && h[x+9][y+2] && h[x+9][y+3] && h[x+9][y+4] && h[x+9][y+5] && h[x+9][y+6] && h[x+9][y+7] && h[x+9][y+8]) a[9]++;                                    
                                        return;    
                                    }
                                    else return;
                                }
                                else return;
                            }
                            else return;
                        }
                        else return;
                    }
                    else return;
                }
                else return;
            }
            else return;
        }
        else return;
    }
    else return;
}
//  Problem #1
//  2 square (s) of size 1
//  1 square (s) of size 2
//  **********************************
int main(){
    int kase = 1;
    while(scanf("%d", &n)!= EOF) {
        scanf("%d", &m);
        if(kase != 1)printf("**********************************\n");
        memset(v,0,sizeof(v));
        memset(h,0,sizeof(h));
        memset(a,0,sizeof(a));

        for( int i = 0; i < m; i++) {
            char s[5];int x1,y1;
            scanf("%s%d%d", s, &x1, &y1);
            if (s[0] == 'H') h[x1][y1] = 1;
            if (s[0] == 'V') v[y1][x1] = 1;
            getchar();
        }
        for(int i = 1; i < 10; i++)
            for(int j = 1; j < 10; j++)
                panduan(i,j);
        printf("Problem #%d\n\n", kase++);
        int flag = 0;
        for(int i = 1; i < 10; i++)
            if(a[i] > 0)
                {flag=1;printf("%d square (s) of size %d\n", a[i], i);}
        if(!flag)printf("No completed squares can be found.\n");
                 
    }
    return 0;
}

/*
H 横边
V 竖边 需要交换一下 x y 如题意
思路 用两个二维数组 存边
遍历点  每个点都判断下 1~9的方形 写个函数就是
try a try,ac is okay
Sample Input
4
16
H 1 1
H 1 3
H 2 1
H 2 2
H 2 3
H 3 2
H 4 2
H 4 3
V 1 1
V 2 1
V 2 2
V 2 3
V 3 2
V 4 1
V 4 2
V 4 3
2
3
H 1 1
H 2 1
V 2 1
Sample Output
Problem #1

2 square (s) of size 1
1 square (s) of size 2

**********************************

Problem #2

No completed squares can be found.

9
32
H 1 1
H 1 2
H 1 3
H 1 4
H 1 5
H 1 6
H 1 7
H 1 8
H 9 1
H 9 2
H 9 3
H 9 4
H 9 5
H 9 6
H 9 7
H 9 8
V 1 1
V 1 2
V 1 3
V 1 4
V 1 5
V 1 6
V 1 7
V 1 8
V 9 1
V 9 2
V 9 3
V 9 4
V 9 5
V 9 6
V 9 7
V 9 8

Problem #1

1 square (s) of size 8

*/
View Code

 

习题 4-3 黑白棋 uva220

 模拟黑白棋, 注意 若当前操控者走不了,就切换另一个操控者 

  解:类似之前的象棋,两个字符串数组 一个存储棋盘 一个存可能的走法 ,但是WA WA WA

 

// 黑白棋  8*8 的棋盘 横竖斜
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>

using namespace std;
char oth[9][9];
bool may[9][9];
char cur,wro;
int x,y,cnt,flag;
void init(char curplayer,char wa){
    for(int i = 1; i < 9; i++)for(int j = 1; j < 9; j++)may[i][j] = false;
    cnt = 0;
    for(int i = 1; i < 9; i++)
            for(int j = 1; j < 9; j++)
                if(oth[i][j] == curplayer)
                {
                    if(oth[i][j+1] == wa)
                        for(int k = j+2; k < 9; k++)
                            {
                                if(oth[i][k] == '-')
                                    {
                                        may[i][k] = true;cnt++;break;
                                    }
                                if(oth[i][k] == curplayer)
                                    break;
                            }
                    if(oth[i][j-1] == wa)
                        for(int k = j-2; k > 0; k--)
                            {
                                if(oth[i][k] == '-')
                                    {
                                        may[i][k] = true;cnt++;break;
                                    }
                                if(oth[i][k] == curplayer)
                                    break;
                            }
                    if(oth[i+1][j] == wa)
                        for(int k = i+2; k < 9; k++)
                            {
                                if(oth[k][j] == '-')
                                    {
                                        may[k][j] = true;cnt++;break;
                                    }
                                if(oth[k][j] == curplayer)
                                    break;
                            }
                    if(oth[i-1][j] == wa)
                        for(int k = i-2; k > 0; k--)
                            {
                                if(oth[k][j] == '-')
                                    {
                                        may[k][j] = true;cnt++;break;
                                    }
                                if(oth[k][j] == curplayer)
                                    break;
                            }
                    if(oth[i+1][j+1] == wa)
                        for(int k = 2; i+k<9 && j+k<9; k++)
                            {
                                if(oth[i+k][j+k] == '-')
                                    {
                                        may[i+k][k+j] = true;cnt++;break;
                                    }
                                if(oth[i+k][j+k] == curplayer)
                                    break;
                            }
                    if(oth[i-1][j-1] == wa)
                        for(int k = 2; i-k>0 && j-k>0; k++)
                            {
                                if(oth[i-k][j-k] == '-')
                                    {
                                        may[i-k][j-k] = true;cnt++;break;
                                    }
                                if(oth[i-k][j-k] == curplayer)
                                    break;
                            }
                    if(oth[i-1][j+1] == wa)
                        for(int k = 2;i-k>0 && j+k<9; k++)
                            {
                                if(oth[i-k][j+k] == '-')
                                    {
                                        may[i-k][j+k] = true;cnt++;break;
                                    }
                                if(oth[i-k][j+k] == curplayer)
                                    break;
                            }
                    if(oth[i+1][j-1] == wa)
                        for(int k = 2;i+k<9 && j-k>0; k++)
                            {
                                if(oth[i+k][j-k] == '-')
                                    {
                                        may[i+k][j-k] = true;cnt++;break;
                                    }
                                if(oth[i+k][j-k] == curplayer)
                                    break;
                            }
                }
}
void bian(char curplayer,char wa){
    int i = x,j = y;
        
    if(oth[i][j+1] == wa)
        for(int k = j+2; k < 9; k++)
            {
                if(oth[i][k] == '-')break;
                if(oth[i][k] == curplayer)
                    {
                        for(int l = k; l >= j; l--)
                            oth[i][l] = curplayer;
                        break;
                    }
            }
    if(oth[i][j-1] == wa)
        for(int k = 2; j-k > 0; k++)
            {
                if(oth[i][j-k] == '-')break;
                if(oth[i][j-k] == curplayer)
                    {
                        for(int l = k; l >= 0; l--)
                            oth[i][j-l] = curplayer;
                        break;
                    }
            }
    if(oth[i+1][j] == wa)
        for(int k = i+2; k < 9; k++)
            {
                if(oth[k][j] == '-')break;
                if(oth[k][j] == curplayer)
                    {            
                        for(int l = k; l >= i; l--)
                            oth[l][j] = curplayer;
                        break;
                    }
            }
    if(oth[i-1][j] == wa)
        for(int k = 2; i-k > 0; k++)
            {
                if(oth[i-k][j] == '-')break;
                if(oth[i-k][j] == curplayer)
                    {
                        for(int l = k; l >= 0; l--)
                            oth[i-l][j] = curplayer;
                        break;
                    }
            }
    if(oth[i+1][j+1] == wa)
        for(int k = 2; i+k<9 && j+k<9; k++)
            {
                if(oth[i+k][j+k] == '-')break;
                if(oth[i+k][j+k] == curplayer)
                    {
                        for(int l = k; l >= 0; l--)
                            oth[i+l][j+l] = curplayer;
                        break;
                    }
            }
    if(oth[i-1][j-1] == wa)
        for(int k = 2; i-k>0 && j-k>0; k++)
            {
                if(oth[i-k][j-k] == '-')break;
                if(oth[i-k][j-k] == curplayer)
                    {
                        for(int l = k; l >= 0; l--)
                            oth[i-l][j-l] = curplayer;
                        break;
                    }
            }
    if(oth[i-1][j+1] == wa)
        for(int k = 2; i-k>0 && j+k<9; k++)
            {
                if(oth[i-k][j+k] == '-')break;
                if(oth[i-k][j+k] == curplayer)
                    {
                        for(int l = k; l >= 0; l--)
                            oth[i-l][j+l] = curplayer;
                        break;
                    }
            }
    if(oth[i+1][j-1] == wa)
        for(int k = 2; j-k>0 && i+k<9; k++)
            {
                if(oth[i+k][j-k] == '-')break;
                if(oth[i+k][j-k] == curplayer)
                    {
                        for(int l = k; l >= 0; l--)
                            oth[i+l][j-l] = curplayer;
                        break;
                    }
            }
}
int main()
{
    int t;int t1 = t;
    cin>>t;
    while(t--){
        if(t1 != t)getchar();
        for(int i = 1;i <= 8; i++)
        {
            string s;
            cin>>s;
            for(int j = 0; j < 8; j++)
                oth[i][j+1] = s[j];
        }
        getchar();
        cur = getchar();wro = (cur == 'B'?'W':'B');
        char cur1 = cur,wro1 = wro;
        init(cur,wro);
        
        while(1){
            char ch = getchar();
            if(ch == 'Q'){
                for(int i = 1; i < 9; i++){for(int j = 1; j < 9; j++)
                    putchar(oth[i][j]);putchar('\n');}
                if(t)printf("\n");
                break;
            }
            if(ch == 'L'){
                int cnt1 = 0;
                //printf("flag=%d cur=%c\n", flag, flag?cur:wro);
                //init(cur,wro);
                int f = 0;
                for(int i = 1; i < 9; i++)for(int j = 1; j < 9; j++)
                    if(may[i][j]){
                        if(!f)printf("(%d,%d)", i, j);else printf(" (%d,%d)", i, j);
                        f = 1;cnt1++;
                    }
                if(f) printf("\n");
            }
            if(ch == 'M'){
                flag = 1;
                scanf("%1d%1d", &x, &y);if(!may[x][y]){
                    puts("No legal move.");
                    flag = 0;
                    bian(wro,cur);
                }
                else bian(cur,wro);
                
                //for(int i = 1; i < 9; i++){for(int j = 1; j < 9; j++)putchar(oth[i][j]);putchar('\n');}
                int b = 0,w = 0;for(int i = 1; i < 9; i++)for(int j = 1; j < 9; j++)
                    {if(oth[i][j] == 'B')b++;if(oth[i][j] == 'W')w++;}
                    printf("Black - %2d White - %2d\n", b, w);
                    if(flag){swap(wro,cur);}
                init(cur,wro);    
                //putchar(curplayer);
        //            printf("  sdsad\n");
            }
        }
    }
    return 0;
}
/*
Sample Input
2
--------
--------
--------
---WB---
---BW---
--------
--------
--------
W
L
M35
L
Q
WWWWB---
WWWB----
WWB-----
WB------
--------
--------
--------
--------
B
L
M25
L
Q
Sample Output
(3,5) (4,6) (5,3) (6,4)
Black -  1 White -  4
(3,4) (3,6) (5,6)
--------
--------
----W---
---WW---
---BW---
--------
--------
--------

No legal move.
Black -  3 White - 12
(3,5)
WWWWB---
WWWWW---
WWB-----
WB------
--------
--------
--------
--------

*/
View Code

 

 

 

习题 4-4 骰子涂色 uva253

 输入一个长度12的字符串 分别表示两个正方体的上前左右后下 六个面

 问是否为同一个正方体 (可通过旋转)

 解:三对两两前后的面 分别与 另一正方形相同即可 

//骰子涂色 touzituse
#include<iostream>
#include<cstdio>
#include<string>
using namespace std;

int main(){
    string s;
    while(cin >> s){
   
        string s11,s12,s13,s21,s22,s23;
    s11 = s[0]+s[5];  s12 = s[1]+s[4];  s13 = s[2]+s[3];
        s21 = s[6]+s[11]; s22 = s[7]+s[10]; s23 = s[8]+s[9];
    //cout<< s << endl;
    //cout<< s11 << s12 << s13 << s21 << s22 << s23 << endl;//乱码??? 为啥输出不了这些个字符串
        /*if((s11==s21 && s12==s22 && s13==s23)||(s11==s22 && s12==s23 && s13==s21)||(s11==s23 && s12==s21 && s13==s22)
        || (s11==s21 && s12==s23 && s13==s22)||(s11==s22 && s12==s21 && s13==s23)||(s11==s23 && s12==s22 && s13==s21))*/
      //直接穷举可能的情况 六种而已 ,有解法反着又来一次 但好像没必要
    
    int flag = 0;
    if ((s11==s21||s11==s22||s11==s23) && (s12==s21||s12==s22||s12==s23) && (s13==s21||s13==s22||s13==s23))
        if ((s21==s11||s21==s12||s21==s13) && (s22==s11||s22==s12||s22==s13) && (s23==s11||s23==s12||s23==s13))
                 flag = 1;

    puts(flag?"TRUE":"FALSE");
    }
  
    return 0;
}
  
View Code

 

习题4-5 IP网络 uva1590

 输入n组IP地址,问最小网络地址与子网掩码

 解:找不同,可以直接用个二维数组 存每个IP地址的32位二进制  ,或者从左到右比较数(我的做法)

#include<algorithm>//IP 网络
#include<cstring>
#include<cstdio>
using namespace std;
const int ma = 1000+10;
int x,y,n;
int a[ma],b[ma],c[ma],d[ma],maxx,minn;
void fin(){
    x = 0,y = 0;int s = 1<<7;//printf("maxx= %d   minn= %d\n", maxx, minn);
    for(int i = 7; i >= 0; i--)
    {
        int t = (maxx/s)&1;
        if(((minn/s)&1) == t)
            x += t*s, y += s;
        else break;
        s /= 2;
    }
}
int main(){
    while(scanf("%d",&n) != EOF)
    {
        memset(a,0,sizeof(a));memset(b,0,sizeof(b));
        memset(c,0,sizeof(c));memset(d,0,sizeof(d));
        for(int i = 1; i <= n; i++)scanf("%d.%d.%d.%d", &a[i], &b[i], &c[i], &d[i]);
        if(n == 1){printf("%d.%d.%d.%d\n255.255.255.255\n", a[1], b[1], c[1], d[1]);}
        else
        {
            sort(a+1,a+n+1);sort(b+1,b+n+1);sort(c+1,c+n+1);sort(d+1,d+n+1);
            if(a[1] == a[n])
            {
                if(b[1] == b[n])
                {
                    if(c[1] == c[n])
                    {
                        if(d[1] == d[n])
                        {
                            printf("%d.%d.%d.%d\n",a[1], b[1], c[1], d[1]);
                            printf("255.255.255.255\n");
                        }
                        else {
                            minn = d[1];maxx = d[n];fin();
                            printf("%d.%d.%d.%d\n", a[1], b[1], c[1], x);
                            printf("255.255.255.%d\n", y);
                        }
                    }
                    else {
                        minn = c[1];maxx = c[n];fin();
                        printf("%d.%d.%d.0\n", a[1], b[1], x);
                        printf("255.255.%d.0\n",  y);
                    }
                }
                else {
                    minn = b[1];maxx = b[n];fin();
                    printf("%d.%d.0.0\n", a[1], x);
                    printf("255.%d.0.0\n", y);//stupid fault
                }
            }
            else {
                minn = a[1];maxx = a[n];fin();
                printf("%d.0.0.0\n", x);
                printf("%d.0.0.0\n", y);
            }
        }
    }
    return 0;
}
View Code

 

习题4-6 莫尔斯密码 uva 508

单个字符编码,给出部分单词 字符串匹配  若多个精确匹配 输出第一个匹配的+! 若无法精确匹配 输出最接近的+?

运用好的容器,事半功倍  自己想来想去都太复杂了 就找了别人的写法

#pragma GCC diagnostic error "-std=c++11"
#include<iostream>
#include<string>//No morse word will have more than eighty (80) elements.
#include<cstdio>//Thered will be at most 100 context words
#include<map>
const int INF = 1e5;
using namespace std;
map<char, string> ascode;
map<string, string> encod;
int dist(string a, string b) {
    if(a.size() > b.size()) swap(a,b);
    if(a == b.substr(0, a.size()))  return b.size()-a.size();
    return INF;
}
string encode(string& s) {
    string ans;
    for(int i = 0; i < s.size(); i++)
        ans += ascode[s[i]];
    return ans;
}
string decode(string s) {
    auto it = encod.begin();
    string ans = it->first;
    //cout<<" || " << ans << endl;
    int dis = dist(it->second, s);
    while(++it != encod.end()) {
        int d = dist(it->second, s);
        if(d < dis) dis = d, ans = it->first;
        else if(d == dis && d == 0 && ans[ans.size()-1] != '!') ans += '!';
    }
    if(dis != 0) ans += '?';
    return ans;
}
int main() {
    string s1,s2;
    while(cin >> s1 && s1[0] != '*') {
    cin >> s2;  
    ascode[s1[0]] = s2;
    //cout<< "ascode."<<s1[0] << "="<<ascode[s1[0]] <<endl;
  }
  while(cin >> s1 && s1[0] != '*') {
    encod[s1] = encode(s1);
    //cout<<s1<<"||"<< encode(s1)<<endl;
  }
  while(cin >> s1 && s1[0] != '*') {
      //cout<<endl<<s1<<"__"<<endl;
      cout<<decode(s1) << endl;    
    }    

    return 0;
}

/*
Sample Input
A .-
B -...
C -.-.
D -..
E .
F ..-.
G --.
H ....
I ..
J .---
K -.-
L .-..
M --
N -.
O ---
P .--.
Q --.-
R .-.
S ...
T -
U ..-
V ...-
W .--
X -..-
Y -.--
Z --..
0 ------
1 .-----
2 ..---
3 ...--
4 ....-
5 .....
6 -....
7 --...
8 ---..
9 ----.
*
AN
EARTHQUAKE
EAT
GOD
HATH
IM
READY
TO
WHAT
WROTH
*
.--.....-- .....--....
--.----.. .--.-.----..
.--.....-- .--.
..-.-.-....--.-..-.--.-.
..-- .-...--..-.--
---- ..--
*
Sample Output
WHAT
HATH
GOD
WROTH?
WHAT
AN
EARTHQUAKE
EAT!
READY
TO
EAT!
*/
View Code

 

xiti 4-7 RAID技术 uva 509 

没看懂题。。。。

#include<bits/stdc++.h>
//给出数据块,判断合法性,合法则恢复并输出完整的数据。非法则报告磁盘非法。 
//合法: 1.任意一列如果没有x则应该满足奇校检或偶校检条件(即1的个数为奇数或者偶数)。 
//2.某一列如果有x,只允许有一个。 
using namespace std;
char mp[8][6420];
int d, s, b;int op;
char c;
int input() {
    cin >> d;
    memset(mp, 0, sizeof(mp));
    if(d == 0) return 0;
    cin >> s >> b;
    cin >> c;
    op = (c=='E')?0:1;
    for(int i = 0; i < d; i++)
        scanf("%s", mp[i]);
    return 1;
}
int isLegal() {
    for(int i = 0; i < s*b; i++) 
    {
        int tag = 0, numx = d, cntx = 0;
        for(int j = 0; j < d; j++) 
        {
            if(mp[j][i] == 'x') 
            {
                if(cntx == 0) 
                {
                    cntx++; numx = j;
                }
                else return 0;
            }
            else {
                if(j == 0) tag = mp[j][i] - '0';
                else tag ^= (mp[j][i] - '0');
            }
        }
        if(cntx == 0 && tag != op) return 0;
        else mp[numx][i] = (tag ^ op) + '0';
    }
    return 1;
}

void recover() {
    string str = "";
    for(int i = 0; i < b; i++) {
        for(int j = 0; j < d; j++) {
            //printf("i=%d  j=%d\n", i, j);
            if(j == i % d) continue;
            for(int k = i*s; k < (i+1)*s; k++) {
                str += mp[j][k];
                //printf("i=%d  j=%d k=%d\n", i, j, k);
            }//cout<< str <<endl;
            //printf("  i=%d  j=%d\n", i, j);
        }
    }
    int tag = 0;
    //cout<< str.length() << endl;
    while(str.length() % 4) str += '0';
    //cout<< str <<endl;
    for(int i = 0; i < str.length(); i += 4) 
    {
        int t = 0;
        for(int j = 0; j < 4; j++) 
        {
            t *= 2;
           
                t += (str[i+j] - '0');
                //cout<< i<< "_" << j << "  "<<str[i+j] <<"__"<<endl;
           
        }
        printf("%X", t);
    }
    cout << endl;
}

int main() {
    //freopen("D:\\input.txt", "r", stdin);
    //freopen("D:\\output.txt", "w", stdout);
    //ios::sync_with_stdio(false);
    int kase = 0;
    while(input()) {
        if(!isLegal())
            printf("Disk set %d is invalid.\n",++kase);
        else{
            printf("Disk set %d is valid, contents are: ",++kase);
            recover();
        }
            /*for(int i = 0; i < s*b; i++) 
            {
                for(int j = 0; j < d; j++) printf("%c", mp[j][i]);
                printf("\n");
            }*/
    }
    return 0;
}
View Code

 

 

习题4-8 特别困的学生 uva 12108

 暴力模拟 、

#include<cstdio>
#define N 298
int main(){
    int n, a[15], b[15], c[15];int cnt, kase = 1;
    while(scanf("%d", &n) , n){
        int sleep = 0,count = 0;
        for(int i = 0; i < n; i++)
                scanf("%d%d%d", &a[i], &b[i], &c[i]);
        
        for(cnt = 1; cnt < N; cnt++){
            count = 0;
            for(int j = 0; j < n; j++){
                if(c[j] <= a[j])
                    count++;
            }
            if(count == n)break;
            for(int j = 0; j < n; j++){
                if(c[j]==(a[j]+b[j]) || (c[j]==a[j] && n-count <= count))
                    c[j] = 0;
                c[j]++;
                //printf("count=%d  c[%d]=%d\n", count, j, c[j]);
            }
        }
        if(cnt == N)cnt = -1;
        printf("Case %d: %d\n", kase++, cnt);
    }
    return 0;
}
View Code

 

习题 4-9 数据挖掘 uva1591

题没看懂。。。 

 

习题 4-10 洪水 uva 815

//题意 可理解为 n*m个山峰, 给定水的体积, 问水能淹过几个山峰,并且最后水位是?
//比如说 给定 3,4,5,6, 7, 8, 9, 11, 12 山峰, 水体积900(底面积100,so 可用高度为9 )
//水只能淹过前面四个山峰, 水平面变成 6+(9-(6*4-3-4-5-6))/4 = 6.75
//有水区域占比则为 4/9 = 44.44%
//将输入的山峰高度 排个序, 有个小技巧 在最高的山峰后面加一个特别大的山峰

//程序实现如下

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>

using namespace std;

int main(){
    int n,m,a[920],kase = 1;
    double sum,he,x,he1;
    while(scanf("%d%d", &n, &m), n) {
        n *= m;
        memset(a, 0, sizeof(a));
        for(int i = 0; i < n; i++)     scanf("%d", a+i);
        sort(a, a+n);
        
        scanf("%lf", &sum);
        sum /= 100.0; he = 0;
        int c;
        a[n] = 0x3f3f3f3f;//???
        for(c = 1; c < n; c++)// == n 
        {
            he += (a[c]-a[c-1])*c;
            
            if(he >= sum)  break;
        }
        for(int i = 0; i < c; i++)    sum += a[i];
        printf("Region %d\n", kase++);
        printf("Water level is %.2lf meters.\n%.2lf percent of the region is under water.\n\n", (sum)*1.0/c, (c)*100.0/n);
    }
    return 0;
}


/*
Sample Input
3 3
25 37 45
51 12 34
94 83 27
10000
0 0
Sample Output
Region 1
Water level is 46.67 meters.
66.67 percent of the region is under water.
*/
View Code
#include <algorithm>
#include <cstdio>
using namespace std;
const int maxn = 35;
 
int a[maxn*maxn], n, m;
 
int main() {
    for (int kase = 1; scanf("%d%d", &n, &m), n&&m; kase++) {
        n *= m;
        for(int i = 0; i < n; i++) scanf("%d", a+i);
        sort(a, a+n);
        a[n] = 0x3f3f3f3f;
 
        int k;
        double sum;
        scanf("%lf", &sum); sum /= 100.0;
        for (k = 1; k <= n; k++) {
            sum += a[k-1];
            if (sum/k <= a[k])
                break;
        }
        printf("Region %d\n", kase);
        printf("Water level is %.2lf meters.\n", sum/k);
        printf("%.2lf percent of the region is under water.\n\n", k*100.0/n);
    }
    return 0;
}
View Code

 

posted @ 2019-06-16 08:54  163467  阅读(179)  评论(0)    收藏  举报