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​为序列中任意一个数):

  1. a i = x a_i=x ai​=x
  2. a i = x a_i=x ai​=x 或 a i = y a_i=y ai​=y,其中 x ≠ y x\not=y x​=y
  3. 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相关推荐

  1. 程序设计思维与实践 csp路径解析、csp炉石传说

    目录 路径解析 输入格式 输出格式 样例 想法: 代码: 炉石传说 描述: 输入格式: 输出格式: 样例: 评测用例规模与约定: 想法: 代码: 路径解析 描述: 在操作系统中,数据通常以文件的形式存 ...

  2. 山东大学程序设计思维与实践 四月模拟:TT与可怜的猫

    4月模拟-TT与可怜的猫 程序设计思维实践-复杂模拟题训练2 山东大学计算机科学与技术学院程序设计思维与实践 sdu程序设计思维与实践 山东大学程序设计思维实践作业 山大程序设计思维实践 山东大学程序 ...

  3. 山东大学计算机科学与技术学院程序设计思维与实践作业 week10-树型数据结构及其应用

    山东大学计算机科学与技术学院程序设计思维与实践作业 山大程序设计思维与实践作业 sdu程序设计思维与实践 山东大学程序设计思维实践作业H10 山大程序设计思维实践作业H10 山东大学程序设计思维与实践 ...

  4. 山大程序设计思维与实践 六月模拟:猪国杀

    六月模拟:猪国杀 山东大学计算机科学与技术学院程序设计思维与实践作业 山大程序设计思维与实践 sdu程序设计思维与实践 山东大学程序设计思维实践作业H 山大程序设计思维实践作业H 山东大学程序设计思维 ...

  5. 程序设计思维与实践 Week9 作业三道

    A - 咕咕东的目录管理器 题面 咕咕东的雪梨电脑的操作系统在上个月受到宇宙射线的影响,时不时发生故障,他受不了了,想要写一个高效易用零bug的操作系统 -- 这工程量太大了,所以他定了一个小目标,从 ...

  6. 山东大学计算机科学与技术学院程序设计思维与实践作业 week5-数学基础与线性结构

    山东大学计算机科学与技术学院程序设计思维与实践作业 山大程序设计思维与实践作业 sdu程序设计思维与实践 山东大学程序设计思维实践作业H5 山大程序设计思维实践作业H5 山东大学程序设计思维与实践 w ...

  7. 程序设计思维与实践 Month3 模拟

    文章目录 CSP 201609-3 炉石传说 1. 问题描述 2. 思路历程 3. 具体实现 4. 代码 CSP 201609-3 炉石传说 1. 问题描述 游戏在一个战斗棋盘上进行,由两名玩家轮流进 ...

  8. 程序设计思维与实践 Week15 作业 A-ZJM与霍格沃兹

    题目链接:A-ZJM与霍格沃兹 题目描述: ZJM 为了准备霍格沃兹的期末考试,决心背魔咒词典,一举拿下咒语翻译题 题库格式:[魔咒] 对应功能 背完题库后,ZJM 开始刷题,现共有 N 道题,每道题 ...

  9. 程序设计思维与实践 月模拟题3 Blog

    CSP-201609-3炉石传说 题目具体描述不再粘贴,如有需要可参照CSP模拟考试网址. CSP模拟考试网址 题目分析 首先构建结构体role用来保存英雄/随从,包含生命值和攻击力两个变量,这样两名 ...

  10. 程序设计思维与实践 Week14 限时大模拟A - 猫睡觉问题

    题意 众所周知,TT家里有一只魔法喵.这只喵十分嗜睡.一睡就没有白天黑夜.喵喵一天可以睡多次!!每次想睡多久就睡多久╭(╯^╰)╮ 喵睡觉的时段是连续的,即一旦喵喵开始睡觉了,就不能被打扰,不然喵会咬 ...

最新文章

  1. Vivado时钟分组约束的三类应用
  2. 1_CUDA编程介绍(20181121)
  3. parent winform 位置_winform 弹出窗体指定位置
  4. 任务分配算法c语言,基于蚁群算法多Agent任务分配方法.pdf
  5. Every column needs a corresponding expression. No expression found for xxxx
  6. linux安装时键盘失灵,在archlinux安装界面这卡住了,鼠标键盘失灵
  7. azure未连接_查找影响Azure成本的未使用资源
  8. 荣耀手表gspro会用鸿蒙,真实使用荣耀手表GS Pro功能用2个月评测反馈!一定看看如何!...
  9. 微型计算机输入输出的工业标准是7位,工业用微型计算机试题3
  10. JavaScript获取浏览器高度和宽度值
  11. java解惑之最后的笑声
  12. CentOS下MySQL安装失败,报socket '/tmp/mysql.sock错误解决方法
  13. JAVA实现Excel照相机功能_excel照相机功能 Excel中鲜为人知的“照相机”功能及使用方法...
  14. 【Python代码】情人节到了,表白代码肯定是少不了的啦
  15. golang转换时间格式报missing Location in call to Date
  16. IE11 F12不能用的问题
  17. 芯旺微 CHIPON 32位机GPIO使用,以KF32A156 IO口的基本使用为例
  18. Generative Adversarial Text to Image Synthesis 论文翻译精校版
  19. 使用Egret粒子编辑器实现烟雾效果
  20. JQuery对DOM的操作【三】

热门文章

  1. 2021年金属非金属矿井通风复审考试及金属非金属矿井通风模拟考试
  2. mysql同步到redis_通过mysql自动同步redis
  3. JAVA关键字 transient 学习总结
  4. 基于强化学习的多智能体任务规划(一)
  5. 经典的设计模式17——中介者模式
  6. Karakurt:一个新型数据盗窃和勒索的黑客组织
  7. 互联网电视和传统电视企业均宣布自家销量第一,到底谁是真第一?
  8. 小程序,大世界-web点播直播入门-代码的自我修养-进阶的直梯
  9. 12.总结-技术亮点
  10. Java学习方法浅谈