多学习。

紫书第四章 函数和递归

例题

组合数

编写函数求  C(m,n) = n!/m!(n-m)! ,其中 m<=n<=25,例如,n=25,m=12时答案为5200300

 

复制代码
#include <iostream>

using namespace std;

long long C(int n,int m)
{
    if(m < n-m) m = n-m;   //约掉较大的那个数
    long long ans = 1;
    for(int i = m+1; i <= n; ++i)
        ans *= i;
    for(int i = 1; i <= n-m; ++i)  //巧妙的n-m,当n-m > m时,约掉n-m,需要除m!,故此时n-m = m
        ans /= i;
    return ans;
}

int main()
{
    int n,m;

    while(~scanf("%d%d",&n,&m))
    {
        printf("%lld\n",C(n,m));
    }

    return 0;
}
复制代码

 

古老的密码(uva1339)

 

 

 

 题解:密码以某种转换规则转换且打乱顺序,要求我们判断此字符串是否为密码根据某种规则转换而来

其实非常简单,既然是根据某种规则转换而来,那么其中某个字符的出现次数都是一定的,

比如说:原串:j有11个 b有3个 加密后j边城a, b变成c,那么加密后a仍有11个,c仍有3个

我们只需要对原串和加密串的各字符进行排序即可,若相同则YES,不同则NO

for(int i = 0; i < n; ++i)
        {
            cnt1[s1[i]]++;
            cnt2[s2[i]]++;
        }
        sort(cnt1.begin(),cnt1.end());
        sort(cnt2.begin(),cnt2.end());

完整代码

复制代码
#include <iostream>
#include <algorithm>
#include <vector>
#define LOCA
using namespace std;

int main()
{
    string s1;
    string s2;
    vector<int> cnt1(150,0);
    vector<int> cnt2(150,0);
    #ifdef LOCAL
    freopen("data.in","r",stdin);
    #endif // LOCAL

    while(cin >> s1 >> s2)
    {
        int n = s1.size();

        fill(cnt1.begin(),cnt1.end(),0);
        fill(cnt2.begin(),cnt2.end(),0);
        for(int i = 0; i < n; ++i)
        {
            cnt1[s1[i]]++;
            cnt2[s2[i]]++;
        }
        sort(cnt1.begin(),cnt1.end());
        sort(cnt2.begin(),cnt2.end());
        bool flag = true;
        for(int i = 0; i < 150 && flag; ++i)
        {
            if(cnt1[i] != cnt2[i])
                flag = false;
        }
        cout << (flag?"YES":"NO") << endl;
    }

    return 0;
}
复制代码

 

刽子手游戏(uva489)

 

 

 

 题解:简单的暴力即可

复制代码
#include <iostream>
#include <cstdio>
#include <set>
#define LOCAL
//注意每个字符错误只能记一次,但曾经正确的答案反复猜也是错
using namespace std;


int main()
{
    int rd;
    set<char> flag;
    string answer;
    string guess;
    int chance;
    #ifdef LOCAL
    freopen("data.in","r",stdin);
    #endif // LOCAL

    while(scanf("%d",&rd) && rd != -1)
    {
        cin >> answer >> guess;
        printf("Round %d\n",rd);
        chance = 7;
        flag.clear();
        int cnt = answer.size();
        for(int i = 0; i < cnt; ++i)
            flag.insert(answer[i]);

        int len = guess.size();
        for(int i = 0; i < len; ++i)
        {
            if(flag.erase(guess[i]) == 0){
                chance--;
            }

            if(flag.empty() || chance == 0)
                break;
        }
        if(chance == 0)
            printf("You lose.");
        else if(flag.empty())
            printf("You win.");
        else
            printf("You chickened out.");
        putchar('\n');
    }

    return 0;
}
复制代码
复制代码
#include <bits/stdc++.h>
#define LOCA
const int maxn = 100;
using namespace std;

char s[maxn],s2[maxn];
int le = 0,chance = 0;
int win,lose;


void guess(char ch)
{
    int bad = 1;
    for(int i = 0; i < strlen(s); ++i)
        if(s[i] == ch)
    {
        bad = 0;
        s[i] = ' ';
        le--;
    }

    if(bad)
        chance--;
    if(!le)
        win = 1;
    else if(!chance)
        lose = 1;
}

int main()
{
    int rd;

    #ifdef LOCAL
    freopen("data.in","r",stdin);
    #endif // LOCAL

    while(scanf("%d",&rd) && rd != -1)
    {
        scanf("%s%s",s,s2);
        printf("Round %d\n",rd);
        win = lose = 0;
        le = strlen(s);
        chance = 7;
        int len  = strlen(s2);
        for(int i = 0; i < len; ++i)
        {
            guess(s2[i]);
            if(win || lose)
                break;
        }

        if(win)
            printf("You win.\n");
        else if(lose)
            printf("You lose.\n");
        else
            printf("You chickened out.\n");
    }

    return 0;
}
复制代码

 

救济金发放(UVA133)

 

 

 

 题解:环。

复制代码
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;

int n,k,m;
bool vis[22];

int guess(int p,int mod,int t)
{
    while(t--)
    {
        do{p = (p+mod-1+n)%n+1;}while(vis[p]);
    }
    return p;
}

int main()
{

    while(~scanf("%d%d%d",&n,&k,&m) && n)
    {
        memset(vis,false,sizeof(vis));
        int left = n;
        int p1 = 0, p2 = n+1;
        while(left)
        {
            p1 = guess(p1,1,k);
            p2 = guess(p2,-1,m);
            vis[p1] = vis[p2] = true;
            printf("%3d",p1);
            left--;
            if(p1 != p2)
                {
                    printf("%3d",p2);
                    left--;
                }
            if(left != 0)
              printf(",");
        }
        putchar('\n');
    }
    return 0;
}
复制代码

 

信息解码(UVA213)

 

 

 

 题解:

复制代码
#include <bits/stdc++.h>
#define LOCAL
using namespace std;

char code[8][1<<8];

char readchar()
{
    int ch;
    while((ch = getchar()) == '\n' || ch == '\r');
    return ch;
}

int readcode()
{
    memset(code,0,sizeof(code));
    code[1][0] = readchar();  //因为第二个样例后会有回车需要readchar

    if(code[1][0] == EOF)
        return 0;

    int ch;
    for(int i = 2; i <= 7; i++)
        for(int j = 0; j < (1<<i)-1; j++)
    {
        ch = getchar();
        if(ch == EOF)
            return 0;
        if(ch == '\n' || ch == '\r')
            return 1;
        code[i][j] = ch;
    }

    return 1;
}

int readint(int len)
{
    int v = 0;
    while(len--)
    {
        v = v*2+( readchar()-'0' );
    }
    return v;
}


int main()
{
    #ifdef LOCAL
    freopen("data.in","r",stdin);
    #endif // LOCAL

   while(readcode())
   {
       int cnt = 0;
       for(;;)
       {
           int len = readint(3);
           if(len == 0)
            break;
           for(;;)
           {
               int t = readint(len);
               if(t == (1 << len)-1)
                break;
               putchar(code[len][t]);
           }
       }
       putchar('\n');
   }

   return 0;
}
复制代码

 

追踪电子表格中的单元格(UVA512)

 

 

 

 

 

 方法一:利用另一个表完成主表的插入删除

复制代码
#include <iostream>
#include <cstdio>
#include <cstring>
#define BIG 1000

const int maxn = 100;
using namespace std;

int d[maxn][maxn],d2[maxn][maxn],ans[maxn][maxn],r,c;
int cols[maxn];

void Copy(char type,int p,int q)
{
    if(type == 'R'){
        for(int i = 1; i <= c; ++i)
            d[p][i] = d2[q][i];
    }
    else if(type == 'C')
    {
        for(int i = 1; i <= r; ++i)
            d[i][p] = d2[i][q];
    }
}


void Dele(char type)
{
    memcpy(d2,d,sizeof(d));
    int n = type=='R'?r:c;
    int cnt = 0;
    for(int i = 1; i <= n; ++i)
    {
        if(!cols[i])
            Copy(type,++cnt,i);
    }
    if(type == 'R')
        r = cnt;
    else
        c = cnt;
}

void Inse(char type)
{
    memcpy(d2,d,sizeof(d));
    int cnt = 0;
    int n = type=='R'?r:c;
    for(int i = 1; i <= n; ++i)
    {
        if(cols[i]) Copy(type,++cnt,0);
        Copy(type,++cnt,i);
    }

    if(type == 'R')
        r = cnt;
    else
        c = cnt;
}

int main()
{
    int kase = 0;
    while(cin >> r >> c && r)
    {
        int n;
        string cmd;
        cin >> n;
        for(int i = 1; i <= r; ++i)
            for(int j = 1; j <= c; ++j)
            d[i][j] = i*BIG+j;
        while(n--)
        {
            memset(cols,0,sizeof(cols));
            cin >> cmd;
            if(cmd[0] == 'E'){
                int r1,c1,r2,c2;
                cin >> r1 >> c1 >> r2 >> c2;
                swap(d[r1][c1],d[r2][c2]);
            }
            else{
                int a,x;
                cin >> a;
                for(int i = 0; i < a; ++i)
                {
                    cin >> x;
                    cols[x] = 1;
                }
                if(cmd[0] == 'D')
                    Dele(cmd[1]);
                else
                    Inse(cmd[1]);
            }
        }
        memset(ans,0,sizeof(ans));
        for(int i = 1; i <= r; ++i)
            for(int j = 1; j <= c; ++j)
            ans[d[i][j]/BIG][d[i][j]%BIG] = i*BIG+j;
        if(kase > 0)
            cout << endl;
            ++kase;
        cout << "Spreadsheet #" << kase << endl;
        cin >> n;
        while(n--)
        {
            int x,y;
            cin >> x >> y;
            printf("Cell data in (%d,%d) ",x,y);
            if(ans[x][y] == 0) printf("GONE");
            else
                printf("moved to (%d,%d)",ans[x][y]/BIG,ans[x][y]%BIG);
            putchar('\n');

        }
    }
    return 0;
}
复制代码

方法二:保存操作,对每个查询的位置推算操作后的位置

复制代码
#include <iostream>
#include <cstdio>
#include <cstring>

using namespace std;

const int maxn = 1000;
int n;
struct Command{
    string c;
    int r1,c1,r2,c2;
    int a,x[20];
}cmd[maxn];


bool simulate(int &x,int &y)
{
    int dr = 0, dc = 0;
    for(int i = 0; i < n; ++i)
    {
        dr = 0,dc = 0;
        if(cmd[i].c[0] == 'E')
        {
            if(cmd[i].r1 == x && cmd[i].c1 == y )
            {
                x = cmd[i].r2;
                y = cmd[i].c2;
            }
            else if(cmd[i].r2 == x && cmd[i].c2 == y)
            {
                x = cmd[i].r1;
                y = cmd[i].c1;
            }
        }
        else
        {
            for(int j = 0; j < cmd[i].a; ++j)
            {
                if(cmd[i].c[0] == 'I'){
                    if(cmd[i].c[1] == 'R' && cmd[i].x[j] <= x) dr++;
                    else if(cmd[i].c[1] == 'C' && cmd[i].x[j] <= y) dc++;
                }
                if(cmd[i].c[0] == 'D'){
                    if(cmd[i].c[1] == 'R' && cmd[i].x[j] < x) dr--;
                    else if(cmd[i].c[1] == 'C' && cmd[i].x[j] < y) dc--;
                    else if(cmd[i].c[1] == 'R' && cmd[i].x[j] == x) return false;
                    else if(cmd[i].c[1] == 'C' && cmd[i].x[j] == y) return false;
                }
            }
            x += dr;
            y += dc;
        }
    }

    return true;
}

int main()
{
    int r,c,kase = 0;
    while(cin >> r >> c && r)
    {
        cin >> n;
        for(int i = 0; i < n; ++i)
        {
            cin >> cmd[i].c;
            if(cmd[i].c[0] == 'E')
            {
                cin >> cmd[i].r1 >> cmd[i].c1 >> cmd[i].r2 >> cmd[i].c2;
            }
            else
            {
                cin >> cmd[i].a;
                for(int j = 0; j < cmd[i].a; ++j)
                    cin >> cmd[i].x[j];
            }
        }
        if(kase != 0)
            cout << endl;
        printf("Spreadsheet #%d\n",++kase);
        int k;
        cin >> k;
        while(k--)
        {
            int x,y;
            cin >> x >> y;
            printf("Cell data in (%d,%d) ",x,y);
            if(!simulate(x,y)) printf("GONE");
            else
                printf("moved to (%d,%d)",x,y);
            putchar('\n');
        }
    }
    return 0;
}
复制代码

 

师兄帮帮忙(UVA124)

 

 

 

 

 

 

 

 

 

 用太多cout会超时:

复制代码
#include <cstdio>
#include <iostream>
#include <vector>
#include <algorithm>
#define EPS 1e-6
using namespace std;

vector<string> sid;
vector<int> cid;
vector<string> name;
vector<vector<int>> scores; //五门成绩,语数英编程和总分


int menu()
{
    cout << "Welcome to Student Performance Management System (SPMS)." << endl;
    cout << endl;
    cout << "1 - Add" << endl;
    cout << "2 - Remove" << endl;
    cout << "3 - Query" << endl;
    cout << "4 - Show ranking" << endl;
    cout << "5 - Show Statistics" << endl;
    cout << "0 - Exit" << endl;
    cout << endl;
    int n;
    cin >> n;
    return n;
}

void add()
{
    string si,na;
    int ci,grade[5];
    cout << "Please enter the SID, CID, name and four scores. Enter 0 to finish." << endl;
    while(cin >> si && si != "0")
    {
        cin >> ci >> na >> grade[0] >> grade[1] >> grade[2] >> grade[3];

         if(find(sid.begin(),sid.end(),si) != sid.end()){
            cout << "Duplicated SID." << endl;
            cout << "Please enter the SID, CID, name and four scores. Enter 0 to finish." << endl;
            continue;
        }
        grade[4] = grade[0]+grade[1]+grade[2]+grade[3];
        sid.push_back(si); cid.push_back(ci);
        name.push_back(na); scores.push_back(vector<int>(grade,grade+5));
        cout << "Please enter the SID, CID, name and four scores. Enter 0 to finish." << endl;
    }
    /*for(int i = 0; i < sid.size(); ++i)
    {
        cout << sid[i] << " " << cid[i] << " " << name[i] << " " ;
        for(int j = 0; j < 5; ++j)
            cout << scores[i][j] << " ";
        cout << endl;
    }*/
}

void remve()
{
    string t;
    cout << "Please enter SID or name. Enter 0 to finish." << endl;
    while(cin >> t && t != "0")
    {
        int n = sid.size(),cnt = 0;
        for(int i = 0; i < n; ++i)
        {
            if(sid[i] == t || name[i] == t)
            {
                sid.erase(sid.begin()+i);
                cid.erase(cid.begin()+i);
                name.erase(name.begin()+i);
                scores.erase(scores.begin()+i);
                cnt++;
            }
        }
        cout << cnt << " student(s) removed." << endl;
        cout << "Please enter SID or name. Enter 0 to finish." << endl;
    }
}

int rak(int i)
{
    int s = scores[i][4];
    int rk = count_if(scores.begin(),scores.end(),[s](vector<int> a){
                        return a[4] > s;
                      }
                      );
    return rk+1;
}

void showRank()
{
    string t;
    int n = sid.size();
    cout << "Please enter SID or name. Enter 0 to finish." << endl;
    while(cin >> t && t != "0")
    {
        for(int i = 0; i < n; ++i)
        {
            if(sid[i] == t || name[i] == t)
            {
                int rk = rak(i);
                cout << rk << " " << sid[i] << " " << cid[i] << " "<< name[i] << " ";
                for(int j = 0; j < 5; ++j)
                    cout << scores[i][j] << " ";
                printf("%.2lf",(double)scores[i][4]/4+EPS);
                cout << endl;
            }
        }
        cout << "Please enter SID or name. Enter 0 to finish." << endl;
    }
}

void joke()
{
    cout << "Showing the ranklist hurts students’ self-esteem. Don’t do that." << endl;
}


void showSta()
{
    cout << "Please enter class ID, 0 for the whole statistics." << endl;
    int c;
    cin >> c;
    int n = sid.size();
    int p[4] = {0};  //各科通过人数
    int f[4] = {0};  //各科挂科人数
    int s[4] = {0}; //四科总分
    int allp[5] = {0};
    for(int i = 0; i < n; ++i)
    {
        if(c == 0 || c == cid[i])
        {
            int cnt = 0;
            int pc = 0;
            for(int j = 0; j < 4; ++j)
            {
                s[j] += scores[i][j];
                if(scores[i][j] >= 60)
                    p[j]++,pc++;
                else
                    f[j]++;
            }
            for(int j = pc; j > 0; --j)
                allp[j]++;
            if(pc == 0)
                allp[0]++;
        }
    }

     cout << "Chinese" << endl;
     cout << "Average Score: ";
     printf("%.2lf\n",(double)s[0]/(p[0]+f[0]));
     cout << "Number of passed students: "<< p[0] << endl;
     cout << "Number of failed students: "<< f[0] << endl << endl;

     cout << "Mathematics" << endl;
     cout << "Average Score: ";
     printf("%.2lf\n",(double)s[1]/(p[1]+f[1]));
     cout << "Number of passed students: "<< p[1] << endl;
     cout << "Number of failed students: "<< f[1] << endl << endl;

     cout << "English" << endl;
     cout << "Average Score: ";
     printf("%.2lf\n",(double)s[2]/(p[2]+f[2]));
     cout << "Number of passed students: "<< p[2] << endl;
     cout << "Number of failed students: "<< f[2] << endl << endl;

     cout << "Programming" << endl;
     cout << "Average Score: ";
     printf("%.2lf\n",(double)s[3]/(p[3]+f[3]));
     cout << "Number of passed students: "<< p[3] << endl;
     cout << "Number of failed students: "<< f[3] << endl << endl;

     cout << "Overall:" << endl;
     cout << "Number of students who passed all subjects: "<< allp[4] << endl;
     cout << "Number of students who passed 3 or more subjects: " << allp[3] << endl;
     cout << "Number of students who passed 2 or more subjects: " << allp[2] << endl;
     cout << "Number of students who passed 1 or more subjects: " << allp[1] << endl;
     cout << "Number of students who failed all subjects: " << allp[0] << endl << endl;
}

int main()
{
    freopen("data.in","r",stdin);
    int choice;
    while((choice = menu()))
    {
        switch(choice)
        {
        case 1:add();
            break;
        case 2:remve();
            break;
        case 3:showRank();
            break;
        case 4:joke();
            break;
        case 5:showSta();
            break;
        }
    }
    return 0;
}
复制代码

优化:

复制代码
#include <bits/stdc++.h>
#define LOCAL
#define maxn 1000
#define maxl 100
#define EPS 1e-6

int n = 0;
char sid[maxn][maxl];
int cid[maxn];
char name[maxn][maxl];
int score[maxn][5]; //第五个记录总分
int removed[maxn] = {0};

using namespace std;

int menu()
{
   int choice;
    printf("Welcome to Student Performance Management System (SPMS).\n");
    printf("\n");
    printf("1 - Add\n");
    printf("2 - Remove\n");
    printf("3 - Query\n");
    printf("4 - Show ranking\n");
    printf("5 - Show Statistics\n");
    printf("0 - Exit\n");
    printf("\n");

    scanf("%d",&choice);

    return choice;
}

bool finded()
{
    for(int i = 0; i < n; i++)
        if(!removed[i] && strcmp(sid[i],sid[n]) == 0 )
            return true;
    return false;
}

void add()
{
    for(;;)
    {
        printf("Please enter the SID, CID, name and four scores. Enter 0 to finish.\n");
        scanf("%s",sid[n]);
        if(strcmp(sid[n],"0") == 0)
            break;
        scanf("%d%s%d%d%d%d",&cid[n],name[n],&score[n][0],&score[n][1],&score[n][2],&score[n][3]);
        if(!finded())
        {
            score[n][4] = score[n][0]+score[n][1]+score[n][2]+score[n][3];
            n++;
        }
        else
            printf("Duplicated SID.\n");
    }
}

int ranks(int index)
{
    int r = 1;
    for(int i = 0; i < n; i++)
      if(!removed[i] && score[i][4] > score[index][4])
        r++;
    return r;
}

void DQ(int isq)
{
    char s[maxl];
    for(;;)
    {
        int r = 0;
         printf("Please enter SID or name. Enter 0 to finish.\n");
         scanf("%s",s);
         if(strcmp(s,"0") == 0)
            break;
         for(int i = 0; i < n; i++) if(!removed[i])
         {
             if(strcmp(s,sid[i]) == 0 || strcmp(s,name[i]) == 0){
                if(isq){
                    printf("%d %s %d %s %d %d %d %d %d %.2f\n",ranks(i),sid[i],cid[i],name[i],score[i][0],score[i][1],score[i][2],
                           score[i][3],score[i][4],(double)score[i][4]/4+EPS);
                }
                else
                {
                    removed[i] = 1;
                    r++;
                }
             }
         }
         if(!isq)
            printf("%d student(s) removed.\n",r);
    }
}

const char course[][18] = {"Chinese","Mathematics","English","Programming"};

int cnt[5];  //全过、过3、过2、过1、全没

void analyize(int c)
{
    memset(cnt,0,sizeof(cnt));

    for(int i = 0; i < n; i++)
        if(!removed[i] && (cid[i] == c || c == 0))
    {
        int flag = 0;
        for(int j = 0; j < 4; j++)
            if(score[i][j] >= 60)
            flag++;
        if(flag == 4)
            cnt[0]++;
        else if(flag == 3)
            cnt[1]++;
        else if(flag == 2)
            cnt[2]++;
        else if(flag == 1)
            cnt[3]++;
        else
            cnt[4]++;
    }
}

double analyize_ave(int c,int index,int &passed,int &failed)
{
    double sum = 0, ave;
    passed = failed = 0;
    for(int i = 0; i < n; i++)
        if(!removed[i] && (c == 0 || c == cid[i]))
    {
        if(score[i][index] >= 60)
            passed++;
        else
            failed++;
        sum += score[i][index];
    }
    if(passed+failed == 0)
        return 0;
    ave = (double)sum/(double)(passed+failed);
    return ave;
}

void show()
{
    int mod;
    printf("Please enter class ID, 0 for the whole statistics.\n");
    scanf("%d",&mod);

    for(int i = 0; i < 4; i++)
    {
        int passed,failed;
        double ave = analyize_ave(mod,i,passed,failed);
        printf("%s\n",course[i]);
        printf("Average Score: %.2f\n", ave+EPS);
                printf("Number of passed students: %d\n", passed);
                printf("Number of failed students: %d\n", failed);
                printf("\n");
    }

    analyize(mod);
    printf("Overall:\n");
     printf("Number of students who passed all subjects: %d\n", cnt[0]);
        printf("Number of students who passed 3 or more subjects: %d\n", cnt[0]+cnt[1]);
        printf("Number of students who passed 2 or more subjects: %d\n", cnt[0]+cnt[1]+cnt[2]);
        printf("Number of students who passed 1 or more subjects: %d\n", cnt[0]+cnt[1]+cnt[2]+cnt[3]);
        printf("Number of students who failed all subjects: %d\n", cnt[4]);
        printf("\n");
}

int main()
{
    int choice;
    #ifdef LOCAL
    freopen("data.in","r",stdin);
    #endif // LOCAL

    while( (choice = menu()) != 0 )
    {
        switch(choice)
        {
            case 1:add();break;
            case 2:DQ(0);break;
            case 3:DQ(1);break;
            case 4:printf("Showing the ranklist hurts students' self-esteem. Don't do that.\n");break;
            case 5:show();break;
        }
    }

    return 0;
}
复制代码

 

习题

象棋(UVA1589)

 

 

 

 

 

 

复制代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>

using namespace std;

int board[12][10];  //用于标记位置上是否有棋子,判断是否蹩脚马
int dir[4][2] = {1,0,-1,0,0,1,0,-1}; //黑将的四个走法
int hdir[8][2] = { {-2,1},{-2,-1},{2,1},{2,-1},{-1,2},{1,2},{-1,-2},{1,-2} };


struct Pos{
    char type;
    int x;
    int y;
    Pos(char t,int xx,int yy):type(t),x(xx),y(yy) {}
};

bool check(bool isG,int x,int y)  //只有黑帅需要移动故我们只判断黑帅即可
{
    if(isG)
        return (y >= 4 && y <= 6) && (x >= 1 && x <= 3);
    else
        return (y >= 1 && y <= 9) && (x >= 1 && x <= 10);
}

int vn(int px,int py,int x) //统计竖直方向与黑帅之间的棋子数
{
    int cnt = 0;
    //找出上方与下方的棋子
    int high = max(px,x);
    int low = min(px,x);

    for(low += 1; low < high; ++low)
        if(board[low][py])
        cnt++;

    return cnt;
}

int hn(int px,int py,int y) //统计水平方向与黑帅之间的棋子数
{
    int cnt = 0;
    //找出左方与右方的棋子
    int low = min(py,y);
    int high = max(py,y);

    for(low += 1; low < high; ++low)
        if(board[px][low])
        cnt++;

    return cnt;
}

int main()
{
    //freopen("data.in","r",stdin);
    int n,px,py;
    while(~scanf("%d%d%d",&n,&px,&py) && n && px && py)
    {
        char type[10];
        int tx,ty;
        memset(board,0,sizeof(board));
        vector<Pos> pv;
        while(n--)
        {
            scanf("%s%d%d",type,&tx,&ty);
            board[tx][ty] = 1;
            pv.push_back(Pos(type[0],tx,ty));
        }

        bool ans = true; //能否将军
        for(int i = 0; i < 4; ++i)
        {
            tx = px+dir[i][0],ty = py+dir[i][1]; //帅的各种走法
            bool live = true; //只要有一种活下就非将军

            if(check(true,tx,ty))
            {
                for(Pos t : pv){
                    if(t.x == tx && t.y == ty) continue; //被帅吃了

                    if(t.type == 'G' && t.y == ty && vn(tx,ty,t.x) == 0){ //红将军与黑帅中间无棋子,将军
                        live = false;
                        break;
                    }
                    else if(t.type == 'R' && ( t.y == ty && vn(tx,ty,t.x) == 0 || t.x == tx && hn(tx,ty,t.y)==0 )){
                            live = false;
                            break;
                    }
                    else if(t.type == 'C' && (  t.y == ty && vn(tx,ty,t.x) == 1 || t.x == tx && hn(tx,ty,t.y)==1) ){
                        live = false;
                        break;
                    }
                    else if(t.type == 'H'){
                        for(int j = 0; j < 8; ++j)
                        {
                            int hx = t.x+hdir[j][0]/2, hy = t.y+hdir[j][1]/2;
                            if(!check(false,hx,hy)) continue;  //陷阱:马会向前走一步再侧走故此步不规范马也不可侧走
                            if(board[hx][hy])
                                continue;
                            int fx = t.x+hdir[j][0],fy = t.y+hdir[j][1];
                            if(fx == tx && fy == ty)
                            {
                                live = false;
                                break;
                            }
                        }
                    }
                    if(live == false){
                            break;
                    }
                }
            }
            if(check(true,tx,ty) && live){
                ans = false;
                break;
            }
        }
        printf("%s\n",ans?"YES":"NO");
    }

    return 0;
}
复制代码

 

posted @   czyaaa  阅读(31)  评论(0编辑  收藏  举报
编辑推荐:
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
点击右上角即可分享
微信分享提示