铺地毯
题目描述
为了准备一个独特的颁奖典礼,组织者在会场的一片矩形区域(可看做是平面直角坐标系的第一象限)铺上一些矩形地毯。一共有 n 张地毯,编号从 1 到 n。现在将这些地毯按照编号从小到大的顺序平行于坐标轴先后铺设,后铺的地毯覆盖在前面已经铺好的地毯之上。
地毯铺设完成后,组织者想知道覆盖地面某个点的最上面的那张地毯的编号。注意:在矩形地毯边界和四个顶点上的点也算被地毯覆盖。
输入格式
输入共 n+2 行。
第一行,一个整数 n,表示总共有 n 张地毯。
接下来的 n 行中,第 i+1 行表示编号 i 的地毯的信息,包含四个整数 a,b,g,k,每两个整数之间用一个空格隔开,分别表示铺设地毯的左下角的坐标 (a,b) 以及地毯在 x 轴和 y 轴方向的长度。
第 n+2 行包含两个整数 x 和 y,表示所求的地面的点的坐标 (x,y)。
输出格式
输出共 1 行,一个整数,表示所求的地毯的编号;若此处没有被地毯覆盖则输出 -1。
分析:
读取输入:
首先读取地毯的数量 n。
然后使用循环依次读取每张地毯的信息,即左下角坐标 (a, b) 以及在 x 轴和 y 轴方向的长度 g 和 k,通过这些信息可以确定地毯的右上角坐标为 (a + g, b + k),并将这些信息以元组或列表的形式存储在一个列表 carpets 中。
最后读取要查询的点的坐标 (x, y)。
检查覆盖情况:
从最后一张地毯(因为后铺的地毯覆盖在前面的上面)开始,也就是从列表 carpets 的最后一个元素开始向前遍历。
对于每张地毯,检查给定点的 x 坐标是否在地毯的 x 坐标范围内(即左下角的 x 坐标 a 到右上角的 x 坐标 a + g 之间),同时检查给定点的 y 坐标是否在地毯的 y 坐标范围内(即左下角的 y 坐标 b 到右上角的 y 坐标 b + k 之间)。
如果点在当前地毯的覆盖范围内,说明这就是覆盖该点的最上面的地毯,输出其编号(编号是从 1 开始的,而列表索引从 0 开始,所以输出索引 i 加 1),然后结束循环。
未找到覆盖地毯的情况:
如果循环结束后都没有找到覆盖该点的地毯,说明该点没有被任何地毯覆盖,此时输出 -1。
代码;
#include<bits/stdc++.h>
const int N= 10000 + 5;
int a[N], b[N], g[N], k[N];
int main() {
int n, x, y;
scanf("%d", &n);
for(int i = 0; i < n; i++) {
scanf("%d%d%d%d", &a[i], &b[i], &g[i], &k[i]);
}
scanf("%d%d", &x, &y);
int ans = -1;
for(int i = 0; i < n; i++) {
if(x >= a[i] && y >= b[i] && x <= a[i] + g[i] && y <= b[i] + k[i]) {
ans = i + 1;
}
}
printf("%d\n", ans);//输出结果
return 0;
}
多项式输出
题目描述
一元 n 次多项式可用如下的表达式表示:
f(x)=anxn+an−1xn−1+⋯+a1x+a0,an=0
其中,aixi 称为 i 次项,ai 称为 i 次项的系数。给出一个一元多项式各项的次数和系数,请按照如下规定的格式要求输出该多项式:
-多项式中自变量为 x,从左到右按照次数递减顺序给出多项式。
-多项式中只包含系数不为 0 的项。
-如果多项式 n 次项系数为正,则多项式开头不出 + 号,如果多项式 n 次项系数为负,则多项式以 - 号开头。
-对于不是最高次的项,以 + 号或者 - 号连接此项与前一项,分别表示此项系数为正或者系数为负。紧跟一个正整数,表示此项系数的绝对值(如果一个高于 0 次的项,其系数的绝对值为 1,则无需输出 1)。如果 x 的指数大于 1,则接下来紧跟的指数部分的形式为“xb”,其中 b 为 x 的指数;如果 x 的指数为 1,则接下来紧跟的指数部分形式为 x;如果 x 的指数为 0,则仅需输出系数即可。
-多项式中,多项式的开头、结尾不含多余的空格。
输入格式
输入共有 2 行
第一行 1 个整数,n,表示一元多项式的次数。
第二行有 n+1 个整数,其中第 i 个整数表示第 n−i+1 次项的系数,每两个整数之间用空格隔开。
输出格式
输出共 1 行,按题目所述格式输出多项式。
代码
#include<bits/stdc++.h>
using namespace std;
signed main(){
int n;
cin>>n;
for(int i=n;i>=0;i--){
int x;
cin>>x;
//x非0
if(x){
if(i!=n&&x>0)
cout<<'+';//不是第一个,才输出+
if(i!=0&&x==-1)
cout<<'-';
if(abs(x)>1||i==0)//输出系数,系数1不用输出,但是如果指数为0需要输出1
cout<<x;
if(i>1)//其他要输出指数
cout<<"x^"<<i;
if(i==1)//1不用输出系数
cout<<'x';
}
}
return 0;
}
生活大爆炸版石头剪刀布
题目描述
石头剪刀布是常见的猜拳游戏:石头胜剪刀,剪刀胜布,布胜石头。如果两个人出拳一样,则不分胜负。在《生活大爆炸》第二季第 8 集中出现了一种石头剪刀布的升级版游戏。
升级版游戏在传统的石头剪刀布游戏的基础上,增加了两个新手势:
斯波克:《星际迷航》主角之一。
蜥蜴人:《星际迷航》中的反面角色。
这五种手势的胜负关系如表一所示,表中列出的是甲对乙的游戏结果。
现在,小 A 和小 B 尝试玩这种升级版的猜拳游戏。已知他们的出拳都是有周期性规律的,但周期长度不一定相等。例如:如果小 A 以 石头-布-石头-剪刀-蜥蜴人-斯波克 长度为 6 的周期出拳,那么他的出拳序列就是 石头-布-石头-剪刀-蜥蜴人-斯波克-石头-布-石头-剪刀-蜥蜴人-斯波克-...,而如果小 B 以 剪刀-石头-布-斯波克-蜥蜴人 长度为 5 的周期出拳,那么他出拳的序列就是 剪刀-石头-布-斯波克-蜥蜴人-剪刀-石头-布-斯波克-蜥蜴人-...。
已知小 A 和小 B 一共进行 N 次猜拳。每一次赢的人得 1 分,输的得 0 分;平局两人都得 0 分。现请你统计 N 次猜拳结束之后两人的得分。
输入格式
第一行包含三个整数:N,NA,NB,分别表示共进行 N 次猜拳、小 A 出拳的周期长度,小 B 出拳的周期长度。数与数之间以一个空格分隔。
第二行包含 NA 个整数,表示小 A 出拳的规律,第三行包含 NB 个整数,表示小 B 出拳的规律。其中,0 表示 剪刀,1 表示 石头,2 表示 布,3 表示 蜥蜴人,4 表示 斯波克。数与数之间以一个空格分隔。
输出格式
输出一行,包含两个整数,以一个空格分隔,分别表示小 A、小 B 的得分。
简单的模拟题
代码:
#include <iostream>
using namespace std;
int N; //猜拳次数int n; //A的猜拳周期长度int m; //B的猜拳周期长度int circle_A[205]; //A的猜拳周期int circle_B[205]; //B的猜拳周期int score_A = 0; //A的得分int score_B = 0; //B的得分int game[5][5] = //游戏的结果情况,1表示A赢,-1表示A输,0表示平
{
{0, -1, 1, 1, -1},
{1, 0, -1, 1, -1},
{-1, 1, 0, -1, 1},
{-1, -1, 1, 0, 1},
{1, 1, -1, -1, 0}
};
int main(void){
cin >> N >> n >> m;
for(int i = 0; i < n; i++)
{
cin >> circle_A[i];
}
for(int i = 0; i < m; i++)
{
cin >> circle_B[i];
}
int i = 0; //遍历A的猜拳周期
int j = 0; //遍历B的猜拳周期
while(N--)
{
if(i >= n)
{
i = 0;
}
if(j >= m)
{
j = 0;
}
int result = game[circle_A[i]][circle_B[j]];
if(result == 1)
{
score_A++;
}
else if(result == -1)
{
score_B++;
}
i++;
j++;
}
cout << score_A << " " << score_B;
return 0;
}
玩具谜题
题目描述
小南有一套可爱的玩具小人,它们各有不同的职业。
有一天,这些玩具小人把小南的眼镜藏了起来。小南发现玩具小人们围成了一个圈,它们有的面朝圈内,有的面朝圈外。如下图:
这时 singer 告诉小南一个谜题:“眼镜藏在我左数第 3 个玩具小人的右数第 1 个玩具小人的左数第 2 个玩具小人那里。”
小南发现,这个谜题中玩具小人的朝向非常关键,因为朝内和朝外的玩具小人的左右方向是相反的:面朝圈内的玩具小人,它的左边是顺时针方向,右边是逆时针方向;而面向圈外的玩具小人,它的左边是逆时针方向,右边是顺时针方向。
小南一边艰难地辨认着玩具小人,一边数着:
singer 朝内,左数第 3 个是 archer。
archer 朝外,右数第 1 个是 thinker。
thinker 朝外,左数第 2 个是 writer。
所以眼镜藏在 writer 这里!
虽然成功找回了眼镜,但小南并没有放心。如果下次有更多的玩具小人藏他的眼镜,或是谜题的长度更长,他可能就无法找到眼镜了。所以小南希望你写程序帮他解决类似的谜题。这样的谜題具体可以描述为:
有 n 个玩具小人围成一圈,已知它们的职业和朝向。现在第 1 个玩具小人告诉小南一个包含 m 条指令的谜題,其中第 z 条指令形如“向左数/右数第 s 个玩具小人”。你需要输出依次数完这些指令后,到达的玩具小人的职业。
输入格式
输入的第一行包含两个正整数 n,m,表示玩具小人的个数和指令的条数。
接下来 n 行,每行包含一个整数和一个字符串,以逆时针为顺序给出每个玩具小人的朝向和职业。其中 0 表示朝向圈内,1 表示朝向圈外。保证不会出现其他的数。字符串长度不超过 10 且仅由英文字母构成,字符串不为空,并且字符串两两不同。整数和字符串之间用一个空格隔开。
接下来 m 行,其中第 i 行包含两个整数 ai,si,表示第 i 条指令。若 ai=0,表示向左数 si 个人;若 ai=1,表示向右数 si 个人。 保证 ai 不会出现其他的数,1≤si<n。
输出格式
输出一个字符串,表示从第一个读入的小人开始,依次数完 m 条指令后到达的小人的职业。
简单的模拟题
代码:
#include <bits/stdc++.h>using namespace std;int main(){
int n,m;
int i,j;
int t = 0;
int op,num;
int a[100001];
string s[100001];
cin>>n>>m;
for(i = 0;i < n;i++)
cin>>a[i]>>s[i];
for(i = 0;i < m;i++)
{
cin>>op>>num;
if(a[t] == 0 && op == 0 || a[t] == 1 && op == 1)
t = t - num;
else
t = t + num;
t=(t%n+n)%n;
}
cout<<s[t];
return 0;
}
乒乓球
题目背景
国际乒联现在主席沙拉拉自从上任以来就立志于推行一系列改革,以推动乒乓球运动在全球的普及。其中 11 分制改革引起了很大的争议,有一部分球员因为无法适应新规则只能选择退役。华华就是其中一位,他退役之后走上了乒乓球研究工作,意图弄明白 11 分制和 21 分制对选手的不同影响。在开展他的研究之前,他首先需要对他多年比赛的统计数据进行一些分析,所以需要你的帮忙。
题目描述
华华通过以下方式进行分析,首先将比赛每个球的胜负列成一张表,然后分别计算在 11 分制和 21 分制下,双方的比赛结果(截至记录末尾)。
比如现在有这么一份记录,(其中 W 表示华华获得一分,L 表示华华对手获得一分):
WWWWWWWWWWWWWWWWWWWWWWLW
在 11 分制下,此时比赛的结果是华华第一局 11 比 0 获胜,第二局 11 比 0 获胜,正在进行第三局,当前比分 1 比 1。而在 21 分制下,此时比赛结果是华华第一局 21 比 0 获胜,正在进行第二局,比分 2 比 1。如果一局比赛刚开始,则此时比分为 0 比 0。直到分差大于或者等于 2,才一局结束。
注意:当一局比赛结束后,下一局立刻开始。
你的程序就是要对于一系列比赛信息的输入(WL 形式),输出正确的结果。
输入格式
每个输入文件包含若干行字符串,字符串由大写的 W 、 L 和 E 组成。其中 E 表示比赛信息结束,程序应该忽略 E 之后的所有内容。
输出格式
输出由两部分组成,每部分有若干行,每一行对应一局比赛的比分(按比赛信息输入顺序)。其中第一部分是 11 分制下的结果,第二部分是 21 分制下的结果,两部分之间由一个空行分隔。
代码:
#include<bits/stdc++.h>using namespace std;char c;string S;int n,a,b;int main(){
while(cin>>c)
{
if(c=='E')break;
S+=c;
}
for(char i:S)
{
if(i=='W')a++;
if(i=='L')b++;
if(max(a,b)>=11&&(abs(a-b)>=2))
{
cout<<a<<":"<<b<<endl;
a=b=0;
}
}
cout<<a<<":"<<b<<endl;
a=b=0;
cout<<endl;
for(char i:S)
{
if(i=='W')a++;
if(i=='L')b++;
if(max(a,b)>=21&&(abs(a-b)>=2))
{
cout<<a<<":"<<b<<endl;
a=b=0;
}
}cout<<a<<":"<<b<<endl;
return 0;
}
数字统计
题目描述
请统计某个给定范围 [L,R] 的所有整数中,数字 2 出现的次数。
比如给定范围 [2,22],数字 2 在数 2 中出现了 1 次,在数 12 中出现 1 次,在数 20 中出现 1 次,在数 21 中出现 1 次,在数 22 中出现 2 次,所以数字 2 在该范围内一共出现了 6 次。
输入格式
2 个正整数 L 和 R,之间用一个空格隔开。
输出格式
数字 2 出现的次数。
简答模拟:
代码:
#include <bits/stdc++.h>
using namespace std;
int main(){
int a,b;
cin>>a>>b;
int res=0;
for(int i=a;i<=b;i++){
int x=i;
while(x){
int tmp=x%10;
if(tmp==2)res++;
x/=10;
}
}
cout<<res;
}
明明的随机数
题目描述
明明想在学校中请一些同学一起做一项问卷调查,为了实验的客观性,他先用计算机生成了 N 个 1 到 1000 之间的随机整数 (N≤100),对于其中重复的数字,只保留一个,把其余相同的数去掉,不同的数对应着不同的学生的学号。然后再把这些数从小到大排序,按照排好的顺序去找同学做调查。请你协助明明完成“去重”与“排序”的工作。
输入格式
输入有两行,第 1 行为 1 个正整数,表示所生成的随机数的个数 N。
第 2 行有 N 个用空格隔开的正整数,为所产生的随机数。
输出格式
输出也是两行,第 1 行为 1 个正整数 M,表示不相同的随机数的个数。
第 2 行为 M 个用空格隔开的正整数,为从小到大排好序的不相同的随机数。
代码:
#include <cstdio>#include <algorithm>#include <bits/stdc++.h>using namespace std;
const int N = 100010;int a[N];int n;
// 快读函数inline int read() {
int x = 0, f = 1;
char ch = getchar();
while (ch < '0' || ch > '9') {
if (ch == '-') f = -1;
ch = getchar();
}
while (ch >= '0' && ch <= '9') {
x = (x << 3) + (x << 1) + (ch ^ 48);
ch = getchar();
}
return x * f;
}
// 三数取中选择基准元素int medianOfThree(int* a, int l, int r) {
int mid = l + (r - l) / 2;
if (a[l] > a[mid]) std::swap(a[l], a[mid]);
if (a[l] > a[r]) std::swap(a[l], a[r]);
if (a[mid] > a[r]) std::swap(a[mid], a[r]);
std::swap(a[l], a[mid]); // 将中位数放到最左边
return a[l];
}
// 分区函数int part(int* a, int l, int r) {
int k = medianOfThree(a, l, r);
int L = l + 1, R = r;
while (true) {
while (L <= r && a[L] < k) L++;
while (a[R] > k) R--;
if (L >= R) break;
std::swap(a[L], a[R]);
L++;
R--;
}
std::swap(a[l], a[R]);
return R;
}
// 快速排序函数void quickSort(int* a, int l, int r) {
if (l >= r) return;
int k = part(a, l, r);
quickSort(a, l, k - 1);
quickSort(a, k + 1, r);
}
int main() {
n = read();
unordered_map<int,int> e;
int m=0;
for (int i = 0; i < n; i++) {
a[i] = read();
if(!e[a[i]])m++;
e[a[i]]=1;
}
cout<<m<<endl;
quickSort(a, 0, n - 1);
int pre=-1;
for (int i = 0; i < n; i++) {
if(a[i]==pre)continue;
if (i > 0) printf(" ");
printf("%d", a[i]);
pre=a[i];
}
printf("\n");
return 0;
}