这几道都是简单的模拟题,但是需要仔细分析和认真的思考其中的细节
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;
}