Nothing for nothing(四)

这几道都是简单的模拟题,但是需要仔细分析和认真的思考其中的细节

 P1003 铺地毯

链接:https://www.luogu.org/problemnew/show/P1003

题意:告诉你每一块地毯的位置以及大小,然后告诉你一个位置,然后问你最后上面覆盖的是哪一块地毯。

题解:根据每一块地毯位置以及大小,求出地毯的范围,然后从第一块地毯遍历到最后一块地毯用cnt来记住符合条件的地毯,当满足条件的时候,不断重新覆盖。cnt就是最后的结果。

#include<stdio.h>
#include<iostream>
using namespace std;
int x[50000], y[50000], ox[50000], oy[50000];
int main(){
    int n;
    while(~scanf("%d", &n)){
        int i, j;
        for(i = 1; i <= n; i++){
            scanf("%d %d %d %d", &x[i], &y[i], &ox[i], &oy[i]);
        }
        int s, t;
        int cnt = -1;
        scanf("%d %d", &s, &t);
        for(i = 1; i <= n; i++){
            int tmp_x = x[i] + ox[i];//横坐标范围
            int tmp_y = y[i] + oy[i];//纵坐标范围
            if((s >= x[i] && s <= tmp_x) && (t >= y[i] && t <= tmp_y)){//是否在这块地毯的范围
                cnt = i;
            }
        }
        if(cnt == -1)printf("-1\n");
        else printf("%d\n", cnt);
    }
return 0;
}

P1067 多项式输出

链接:https://www.luogu.org/problemnew/show/P1067

题意:给你一定的数让你按照多项式的形式输出。

题解:本题就是纯模拟,但是有些小细节,首先就是如果某个数为+1或-1那么这个单项式,中的1不能输出,如果x的指数为1,这个1也不能输出。如果中间的数位复数的时候加号不输出,如果这个数为零的时候这一项直接跳过。

#include<stdio.h>
#include<iostream>
using namespace std;
int num[202];
int main(){
    int n;
    while(~scanf("%d", &n)){
          int i, t;
          for(i = 0; i <= n; i++){
             scanf("%d", &num[i]);
          }
          int cnt = 0;
          int cn = 0;
          for(i = 0; i < n - 1; i++){
            if(num[i] == 0){//如果这个数为0那么就不会输出,直接跳过
                    cnt++;
                    continue;
            }
            else {
                    cn++;
                    if(cn != 1 && num[i] > 0)printf("+");
                    if(num[i] == 1)printf("x^%d",n - i);
                    else if(num[i] == -1)printf("-x^%d", n - i);
                    else printf("%dx^%d", num[i],n - i);
            }

          }
          if(num[n -1] == 0){//倒数第二项
            cnt++;
          }
          else {
            if(num[n - 1] > 0 && cnt != n - 1)printf("+");
            if(num[n - 1] == 1)printf("x");
            else if(num[n - 1] == -1)printf("-x");
            else printf("%dx", num[n-1]);
          }
          if(num[n] == 0){
             if(cnt == n)printf("0");
          }
          else {
                if(num[n] > 0 && cnt != n )printf("+");
                printf("%d", num[n]);
          }
          printf("\n");
    }
return 0;
}

P1540 机器翻译

链接:https://www.luogu.org/problemnew/show/P1540

题意:给一串数字,查询之后储存在内存里,如果有内存中有这个数字,那么就不用查询了, 如果没有还需查询。因为内存的原因,当查询的个数大于内存时,最开始的存入内存的数字就清空,求出查询的个数。

题解:该题也是纯模拟题,但是用queue 比较好,用两个queue,一个用来剔除,另外一个用来查询,如果查询到,直接跳过,否则直接剔除首位的数,并且队列中加入新查询的数。

#include<stdio.h>
#include<iostream>
#include<queue>
using namespace std;
int n, m;
queue<int>q, p;
int main(){
    while(~scanf("%d %d", &n, &m)){
        int i, j, t, cnt = 0;
        for(i = 0; i < m; i++){
            int flag = 0;
            scanf("%d", &t);
            if(q.size() > n)q.pop();//如果大于内存删除首位
            p = q;//p队列用来查询
            while(!p.empty()){//查找这个数是否在内存中, 遍历
                int a = p.front();
                if(a == t){
                    flag = 1;//如果存在标记一下
                    break;
                }
                 p.pop();
            }
            if(flag == 0){//不存在就加入队列
                cnt++;
                q.push(t);
            }

        }
        printf("%d\n", cnt);
    }
return 0;
}

 P1056 排座椅

链接:https://www.luogu.org/problemnew/show/P1056

题意:用最少的通道,尽量把爱说话的人隔离开,爱说话的人是成对的,不是一对的不爱说话。

题解:如果这两横坐标一样,那么按照纵坐标最小的那一个隔离,同理纵坐标一样,那么按照横坐标最小的那个隔离,然后按照桶排的方法来查找能拆分的最有效的一个,然后用另外一个数组储存。然后排序输入,输出结果。

#include<stdio.h>
#include<iostream>
#include<queue>
#include<string.h>
#include<math.h>
#include<algorithm>
using namespace std;
int a[10000], b[10000], p[10000], q[10000];
int m, n, k,l, d;
bool cmp(int a, int b){
     return a > b;
}
int main(){
    while(~scanf("%d %d %d %d %d", &m, &n, &k, &l, &d)){
         int x1, y1, x2, y2;
         int i, j;
         for(i = 1; i <= d; i++){
             scanf("%d %d %d %d", &x1, &y1, &x2, &y2);
             int z;
             if(x1 == x2){//横坐标相同
                z = min(y1, y2);//最小的纵坐标
                a[z]++;
             }
             if(y1 == y2){//纵坐标相同
                z = min(x1, x2);//最小的横坐标
                b[z]++;
             }
         }
        int f = k, g =  l;
        int cn = 0;
        while(f--){//最大的通道
           int maxn = -1, t;
           for(i = 1; i <= n; i++){
               if(b[i] > maxn){
                        maxn = b[i];
                        t = i;
                }

            }
            b[t] = 0;
            p[cn++] = t;//储存最大的通道
        }

         int cnt = 0;
          while(g --){
            int maxn = -1, t;
          for(i = 1; i <= m ; i++){
               if(a[i] > maxn){
                       maxn = a[i];
                       t = i;
                }

           }
           a[t] = 0;
           q[cnt++] = t;
        }
        sort(p, p + cn);//排序输出
        sort(q, q + cnt);
        for(i = 0; i < k; i++){
            printf("%d", p[i]);
            if(i != k - 1)printf(" ");
        }
        printf("\n");
        for(i = 0; i < l; i++){
            printf("%d", q[i]);
            if(i != l -1)printf(" ");
        }
        printf("\n");


   }
return 0;
}

P1328 生活大爆炸版石头剪刀布

链接:https://www.luogu.org/problemnew/show/P1328

题意:按照一定顺序出石头剪刀不...给出竞赛的个数,图中给出规则,给出两人胜出的个数。

题解:先把规则给写出来用他来判断谁输谁嬴。

#include<stdio.h>
#include<iostream>
#include<queue>
using namespace std;
int a[201], b[201];
int n, m, t;
int main(){
    while(~scanf("%d %d %d", &t, &m, &n)){
         int i;
         for(i = 0; i < m; i++)scanf("%d", &a[i]);
         for(i = 0; i < n; i++)scanf("%d", &b[i]);
         int cnt = 0, tx = 0, ty = 0;
         int sa = 0, sb = 0;
         while(cnt < t){
            if(cnt >= m && tx >= m)tx = 0;//如果tx>0, 那么就重新开始
            if(cnt >= n && ty >= n)ty = 0;

            if((a[tx] == 1 && b[ty] == 0) || (a[tx] == 4 && b[ty] == 0) ||  //A胜出的条件
               (a[tx] == 2 && b[ty] == 1) || (a[tx] == 4 && b[ty] == 1) ||
               (a[tx] == 0 && b[ty] == 2) || (a[tx] == 3 && b[ty] == 2) ||
               (a[tx] == 2 && b[ty] == 4) || (a[tx] == 3 && b[ty] == 4) ||
               (a[tx] == 0 && b[ty] == 3) || (a[tx] == 1 && b[ty] == 3)
               ){
                sa++;
            }
            else if(a[tx] == b[ty]){}//平局的条件
            else sb++;//B胜出的条件
            cnt++;
            tx++;
            ty++;
         }
         printf("%d %d\n", sa, sb);
    }
return 0;
}

P1563 玩具谜题

链接:https://www.luogu.org/problemnew/show/P1563

题意:一堆人站在一圈,从第一个人开始,如果告诉你几个查找的条件,最后输出找到的那个人。

题解:如果 内圈 左边  cnt加,内圈 右边  cnt减,外圈 左边 cnt减, 外圈 右边 cnt加。

#include<stdio.h>
#include<iostream>
#include<queue>
using namespace std;
//本题就是 一个模拟题主要是搞清楚方向,和如何去运算的
int a[100002], b[100002][20];
int s, t;
int main(){
    int n, m;
    while(~scanf("%d %d", &n, &m)){
         int i, j;
         int s,t;
         for(i = 1; i <= n; i++){
            scanf("%d", &a[i]);
            scanf("%s", b[i]);
         }
         int cnt = 1, cn;//cnt用来记录位置
         for(i = 1; i <= m; i++){
             scanf("%d %d",&s, &t);
             if(a[cnt] == 0){//向内
                if(s == 0){//向左
                        cnt = cnt - t;
                        if(cnt <= 0)cnt += n;
                }
                else {//向右
                        cnt += t;
                        if(cnt > n)cnt %= n;
                }

             }
             else {//向外
                if(s == 0){//向左
                    cnt += t;
                    if(cnt > n)cnt %= n;
                }
                else {//向右
                      cnt = cnt - t;
                      if(cnt < 0)cnt += n;
                }
             }
         }
         printf("%s\n", b[cnt]);


    }
return 0;
}

猜你喜欢

转载自blog.csdn.net/REfusing/article/details/81209115