程序设计思维与实践 CSP-M2
HRZ的序列
相较于咕咕东,瑞神是个起早贪黑的好孩子,今天早上瑞神起得很早,刷B站时看到了一个序列a,他对这个序列产生了浓厚的兴趣,他好奇是否存在一个数K,使得一些数加上K,一些数减去K,一些数不变,使得整个序列中所有的数相等,其中对于序列中的每个位置上的数字,至多只能执行一次加运算或减运算或是对该位置不进行任何操作。由于瑞神只会刷B站,所以他把这个问题交给了你!
输入格式
输入第一行是一个正整数t表示数据组数。接下来对于每组数据,输入的第一个正整数n表示序列a的长度,随后一行有n个整数,表示序列a。
输出格式
输出共包含t行,每组数据输出一行。对于每组数据,如果存在这样的K,输出"YES",否则输出“NO"。
(输出不包含引号)
样例输入
2
5
1 2 3 4 5
5
1 2 3 4 5
样例输出
NO
NO
数据范围
思路
根据题意,这样的序列只能是以下三种形式之一( a i a_i ai为序列中任意一个数):
- a i = x a_i=x ai=x
- a i = x a_i=x ai=x 或 a i = y a_i=y ai=y,其中 x ≠ y x\not=y x=y
- a i = x a_i=x ai=x 或 a i = y a_i=y ai=y 或 a i = z a_i=z ai=z,其中 x < y x<y x<y & & \&\& && y < z y<z y<z,且 y − x = z − y y-x=z-y y−x=z−y
其他的情况都不满足要求
因此要记录序列中不相等的数字,这时
set是一个很好的方法,set可以自动去重。
当set中的数的个数为1或2时,是上面的情况1和情况2,这时肯定满足
if(s.size()==2 || s.size()==1)printf("YES\n");
当set中的数的个数为3时,需要判断一下,因为有可能这三个数不构成等差数列。
else if(s.size()==3){auto begin=s.begin();auto mid=++(s.begin());auto end=s.rbegin();int minNum=min(min(*begin,*mid),*end);int maxNum=max(max(*begin,*mid),*end);int midNum=*begin+*end+*mid-minNum-maxNum;if(minNum+maxNum == midNum*2)printf("YES\n");elseprintf("NO\n");}
在使用迭代器的时候需要小心,比如
auto begin=s.begin();
auto mid=++begin;
这样写时,begin会在后面改变,这样写更好
set<long long>:: iterator it = s. begin();
long long a=*(it++), b=*(it++), c=*(it++);
还需要注意的是,set每次使用时要清空
代码
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <set>
using namespace std;set<long long int> s;
int t,n;int main(){scanf("%d",&t);for(int u=0;u<t;u++){scanf("%d",&n);s.clear();for(int i=0;i<n;i++) {long long int temp;scanf("%lld",&temp);s.insert(temp);
// scanf("%lld",arr+i);} if(s.size()==2 || s.size()==1)printf("YES\n");else if(s.size()==3){auto begin=s.begin();auto mid=++(s.begin());auto end=s.rbegin();int minNum=min(min(*begin,*mid),*end);int maxNum=max(max(*begin,*mid),*end);int midNum=*begin+*end+*mid-minNum-maxNum;if(minNum+maxNum == midNum*2)printf("YES\n");elseprintf("NO\n");}elseprintf("NO\n");}return 0;
}
HRZ学英语
瑞神今年大三了,他在寒假学会了英文的26个字母,所以他很兴奋!于是他让他的朋友TT考考他,TT想到了一个考瑞神的好问题:给定一个字符串,从里面寻找连续的26个大写字母并输出!但是转念一想,这样太便宜瑞神了,所以他加大了难度:现在给定一个字符串,字符串中包括26个大写字母和特殊字符’?’,特殊字符‘?’可以代表任何一个大写字母。现在TT问你是否存在一个位置连续的且由26个大写字母组成的子串,在这个子串中每个字母出现且仅出现-次,如果存在,请输出从左侧算起的第一个出现的符合要求的子串,并且要求,如果有多组解同时符合位置最靠左,则输出字典序最小的那个解!如果不存在,输出-1!这下HRZ蒙圈了,他刚学会26个字母,这对他来说太难了,所以他来求助你,请你帮他解决这个问题,报酬是可以帮你打守望先锋。
说明:字典序先按照第一个字母,以A、B、…的顺序排列;如果第-个字母样,那么比较第二个、第三个乃至后面的字母。如果比到最后两个单词不一样长(比如,SIGH 和SIGHT),那么把短者排在前。例如
AB??EFGHIJKLMNOPQRSTUVWXYZ ABCDEFGHIJKLMNOPQRSTUVWXYZ
ABDCEFGHIJKLMNOPQRSTUVWXYZ
上面两种填法,都可以构成26个字母,但是我们要求字典序最小,只能取前者。
注意,题目要求的是第一个出现的,字典序最小的!
输入格式
输入只有一行,一个符合题目描述的字符串。
输出格式
输出只有一行,如果存在这样的子串,请输出,否则输出-1
样例输入1
ABC??FGHIJK???OPQR?TUVWXY?
样例输出1
ABCDEFGHIJKLMNOPQRSTUVWXYZ
样例输入2
AABCDEFGHIJKLMNOPQRSTUVW??M
样例输出2
-1
数据范围
思路
题目要求判断一个位置连续的由26个大写字母组成的子串,因此使用固定大小(26)的滑动窗口,从左到右移动,遇到满足要求的子串处理并返回,这样就保证了是第一个出现的。
该如何判断一个子串是否满足要求呢?如果一个字母出现了两次,不满足;如果?不能完全替换没有出现的字母,也不满足。
bool check(){int temp=0;for(int i=0;i<=25;i++){if(cnt[i]==0) temp++;else if(cnt[i]>=2) {return false;}}return temp==cnt[26];
}
在用?替换子串时,如果在判断的时候记录没有出现的字母的位置,需要将这个记录放在滑动窗口里(随着滑动窗口的移动而更新),使用队列来记录,如果每次判断都要重新来记录没有出现的字母的位置的话会超时。也可以在找到满足要求的字串后在记录。
int index=0;char arr[30];for(int i=0;i<26;i++)if(cnt[i]==0)arr[index++]=(char)(i+'A');index=0;for(int i=l;i<=r;i++){if(str[i]!='?') printf("%c",str[i]);else{printf("%c",arr[index]);index++;}}printf("\n");
代码
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <queue>
using namespace std;const int maxLen=1e6+5;
char str[maxLen];
int cnt[27];
int l,r;bool check(){int temp=0;for(int i=0;i<=25;i++){if(cnt[i]==0) temp++;else if(cnt[i]>=2) {return false;}}return temp==cnt[26];
}int main(){memset(str,0,sizeof str);memset(cnt,0,sizeof cnt);scanf("%s",str);if(strlen(str)<26){printf("-1\n");return 0;} l=0;r=25;for(int i=0;i<=25;i++){if(str[i]!='?') cnt[str[i]-'A']++;else cnt[26]++;}while(r<strlen(str)){if(check()){int index=0;char arr[30];for(int i=0;i<26;i++)if(cnt[i]==0)arr[index++]=(char)(i+'A');index=0;for(int i=l;i<=r;i++){if(str[i]!='?') printf("%c",str[i]);else{printf("%c",arr[index]);index++;}}printf("\n");return 0;}if(str[l]!='?') cnt[str[l]-'A']--;else cnt[26]--;l++;r++;if(r==strlen(str)) break;if(str[r]!='?') cnt[str[r]-'A']++;else cnt[26]++;} printf("-1\n");return 0;
}
咕咕东的奇妙序列
咕咕东正在上可怕的复变函数,但对于稳拿A Plus的咕咕东来说,她早已不再听课,此时她在睡梦中突然想到了一个奇怪的无限序列:112123123412345…这个序列由连续正整数组成的若干部分构成,其中第一部分包含1至1之间的所有数字,第二部分包含1至2之间的所有数字,第三部分包含1至3之间的所有数字,第i部分总是包含1至i之间的所有数字。所以,这个序列的前56项会是
11212312341234512345612345671234567812345678912345678910,其中第1项是1,第3项是2,第20项是5,第38项是2,第56项是0。咕咕东现在想知道第k项数字是多少!但是她睡醒之后发现老师讲的东西已经听不懂了,因此她把这个任务交给了你。
输入格式
输入由多行组成。
第一行一个整数q表示有q组询问(1 <=q <= 500)
接下来第i+1行表示第i个输入k,表示询问第k,项数字。(1 <= k i k_i ki<= 1018)
输出格式
输出包含q行
第i行输出对询问 k i k_i ki的输出结果。
样例输入
5
1
3
20
38
56
样例输出
1
2
5
2
0
数据规模
思路
这个序列很有规律,每一个部分都是从1到n开始的连续数字串,可以把每一个部分看作是大序列的基本单元。part n 的长度构成了一个公差为2的等差数列,要确定x是在哪一个part 里,就要将前面的part的长度累加,如果x很大的话part n 的长度会累加很多项,如果二分的话又不太清楚二分的上界part是多少(但是可以先计算一下),这里首先确定x是在哪个范围的part里,即确定part n 的n 是几位数。
确定好了part的范围就开始对part进行二分,此时x可以更新为x到part范围的左边界的长度,这样不断二分最后就确定了是在哪一个part里(part mid里),而且此时x是所求的数相对于part mid 的偏移量(这时可能part mid 还是很长)
由于一个part里还是由很多数字组成的,即1 2 3 4 … 10 11 12 … 100 101 102 … n ,要确定具体是在哪一个数字里。
确定了具体是在bit位的第num+1个数字里,而且偏移量更新为x,这时可以使用stringstream来将数字转换为字符串,也可以不断除以10最后模10来找到偏移量为x 的那个数
或许画图+举例更容易理解
代码
#include <iostream>
#include <stdio.h>
#include <string>
#include <sstream>
#include <string>
#include <cmath>
using namespace std;void getlen(long long int x){long long int total=0,last=0,first=0,before=0;int bit=1;while(total<=x){first=last+bit;last+=9*pow(10,bit-1)*bit;before=total;total+=(first+last)*9*pow(10,bit-1)/2;bit++;}bit--;//二分partx=x-before;long long int lp,rp,mp,mid,ans=0,temp=0;long long int lp_len=0,rp_len=0;lp=pow(10,bit-1);rp=pow(10,bit)-1;while(lp<=rp){mp=(lp+rp)/2;mid=first+(mp-lp)*bit;temp=(first+mid)*(mp-lp+1)/2;if(x>=temp){//在右边 lp=mp+1;first=mid+bit;x-=temp;}else{//在左边 rp=mp-1;last=mid-bit;}}long long int cnt=1,num=0,number=0;while(x>=0){last=x;x-=9*pow(10,cnt-1)*cnt;cnt++;}cnt--;num=last/cnt;//结果是在num+1个数里x=last-num*cnt;//第i位 number=pow(10,cnt-1)+num;long long int te=number;for(int i=1;i<cnt-x;i++){te/=10;}printf("%d\n",te%10);
}int q;
long long int ans,k;int main(){scanf("%d",&q);for(int i=0;i<q;i++){scanf("%lld",&k);getlen(k-1);}return 0;
}
程序设计思维与实践 CSP-M2相关推荐
- 程序设计思维与实践 csp路径解析、csp炉石传说
目录 路径解析 输入格式 输出格式 样例 想法: 代码: 炉石传说 描述: 输入格式: 输出格式: 样例: 评测用例规模与约定: 想法: 代码: 路径解析 描述: 在操作系统中,数据通常以文件的形式存 ...
- 山东大学程序设计思维与实践 四月模拟:TT与可怜的猫
4月模拟-TT与可怜的猫 程序设计思维实践-复杂模拟题训练2 山东大学计算机科学与技术学院程序设计思维与实践 sdu程序设计思维与实践 山东大学程序设计思维实践作业 山大程序设计思维实践 山东大学程序 ...
- 山东大学计算机科学与技术学院程序设计思维与实践作业 week10-树型数据结构及其应用
山东大学计算机科学与技术学院程序设计思维与实践作业 山大程序设计思维与实践作业 sdu程序设计思维与实践 山东大学程序设计思维实践作业H10 山大程序设计思维实践作业H10 山东大学程序设计思维与实践 ...
- 山大程序设计思维与实践 六月模拟:猪国杀
六月模拟:猪国杀 山东大学计算机科学与技术学院程序设计思维与实践作业 山大程序设计思维与实践 sdu程序设计思维与实践 山东大学程序设计思维实践作业H 山大程序设计思维实践作业H 山东大学程序设计思维 ...
- 程序设计思维与实践 Week9 作业三道
A - 咕咕东的目录管理器 题面 咕咕东的雪梨电脑的操作系统在上个月受到宇宙射线的影响,时不时发生故障,他受不了了,想要写一个高效易用零bug的操作系统 -- 这工程量太大了,所以他定了一个小目标,从 ...
- 山东大学计算机科学与技术学院程序设计思维与实践作业 week5-数学基础与线性结构
山东大学计算机科学与技术学院程序设计思维与实践作业 山大程序设计思维与实践作业 sdu程序设计思维与实践 山东大学程序设计思维实践作业H5 山大程序设计思维实践作业H5 山东大学程序设计思维与实践 w ...
- 程序设计思维与实践 Month3 模拟
文章目录 CSP 201609-3 炉石传说 1. 问题描述 2. 思路历程 3. 具体实现 4. 代码 CSP 201609-3 炉石传说 1. 问题描述 游戏在一个战斗棋盘上进行,由两名玩家轮流进 ...
- 程序设计思维与实践 Week15 作业 A-ZJM与霍格沃兹
题目链接:A-ZJM与霍格沃兹 题目描述: ZJM 为了准备霍格沃兹的期末考试,决心背魔咒词典,一举拿下咒语翻译题 题库格式:[魔咒] 对应功能 背完题库后,ZJM 开始刷题,现共有 N 道题,每道题 ...
- 程序设计思维与实践 月模拟题3 Blog
CSP-201609-3炉石传说 题目具体描述不再粘贴,如有需要可参照CSP模拟考试网址. CSP模拟考试网址 题目分析 首先构建结构体role用来保存英雄/随从,包含生命值和攻击力两个变量,这样两名 ...
- 程序设计思维与实践 Week14 限时大模拟A - 猫睡觉问题
题意 众所周知,TT家里有一只魔法喵.这只喵十分嗜睡.一睡就没有白天黑夜.喵喵一天可以睡多次!!每次想睡多久就睡多久╭(╯^╰)╮ 喵睡觉的时段是连续的,即一旦喵喵开始睡觉了,就不能被打扰,不然喵会咬 ...
最新文章
- Vivado时钟分组约束的三类应用
- 1_CUDA编程介绍(20181121)
- parent winform 位置_winform 弹出窗体指定位置
- 任务分配算法c语言,基于蚁群算法多Agent任务分配方法.pdf
- Every column needs a corresponding expression. No expression found for xxxx
- linux安装时键盘失灵,在archlinux安装界面这卡住了,鼠标键盘失灵
- azure未连接_查找影响Azure成本的未使用资源
- 荣耀手表gspro会用鸿蒙,真实使用荣耀手表GS Pro功能用2个月评测反馈!一定看看如何!...
- 微型计算机输入输出的工业标准是7位,工业用微型计算机试题3
- JavaScript获取浏览器高度和宽度值
- java解惑之最后的笑声
- CentOS下MySQL安装失败,报socket '/tmp/mysql.sock错误解决方法
- JAVA实现Excel照相机功能_excel照相机功能 Excel中鲜为人知的“照相机”功能及使用方法...
- 【Python代码】情人节到了,表白代码肯定是少不了的啦
- golang转换时间格式报missing Location in call to Date
- IE11 F12不能用的问题
- 芯旺微 CHIPON 32位机GPIO使用,以KF32A156 IO口的基本使用为例
- Generative Adversarial Text to Image Synthesis 论文翻译精校版
- 使用Egret粒子编辑器实现烟雾效果
- JQuery对DOM的操作【三】