## Problem A
题意:
解题说明:此题其实是求两段区间的交集,注意要去除掉交集中的某个点。
题解:
C++版本一
#include<cstdio> #include<iostream> #include<algorithm> #include<cstring> #include<string> #include<cmath> int main() { long long int l1,r1,l2,r2,k,x,y; scanf("%lld%lld%lld%lld%lld",&l1,&r1,&l2,&r2,&k); x=(l1>=l2)?l1:l2; y=(r1<=r2)?r1:r2; if(r1<l2||r2<l1) { printf("0\n"); } else { if(x<=k&&k<=y) { printf("%lld\n",y-x); } else { printf("%lld\n",y-x+1); } } return 0; }
## Problem B
题意:
给定一个序列,对于每一个元素,只能 + 或者 - 一个数val。这个数一旦选定,就不能改。
问能否变成全部数字都一样。
题解:
这题的正解是观察法。也可以证明。
①、全部数字都一样、有两个不同数字、三个不同数字(a[1] + a[3] = 2 * a[2])这些都易懂
那4个不同数字为什么是no呢
可以想象成找不到一个点,作为圆心,包含另外3个点(这3点在一直线)。
所以对于有三个不同数字那个,其实就是判断是否为圆心。
C++版本一
#include <bits/stdc++.h> using namespace std; const int N = 5000000+10; int a[N]; int main(int argc, char const *argv[]) { int n; cin >> n ; for(int i = 1;i <= n ; i ++) cin >> a[i]; sort(a + 1, a + 1 + n ); int x = unique(a+1,a + n+1) - a - 1; //cout << a[1] << a[2] << a[3] << a[4] << endl; //cout << x << endl; if(x < 3 || (x == 3 &&a[2] - a[1] == a[3] - a[2] )){ cout << "YES" << endl;} else cout << "NO" << endl; return 0; }
## Problem C
题意:
题解:
字典树
C++版本一
#include <bits/stdc++.h> using namespace std; const int N = 5000000+10; struct Trie { int ch[N][3]; int sz; int val[N]; void Init() { sz=1; memset(ch,0,sizeof ch); memset(val,0,sizeof val); } void Insert(char *num,int op) { int u=0; for(int i=20;i>=strlen(num);i--) { if(ch[u][0]==0) ch[u][0]=sz++; u=ch[u][0]; } for(int i=0;i<strlen(num);i++) { int c=(num[i]-'0')%2; if(ch[u][c]==0) ch[u][c]=sz++; u=ch[u][c]; } val[u]+=op; } int Find(char *num) { int u=0; int cur=0; for(int i=20;i>=strlen(num);i--) { if(ch[u][0]==0) return 0; u=ch[u][0]; cur+=val[u]; } for(int i=0;i<strlen(num);i++) { int c=(num[i]-'0')%2; if(ch[u][c]==0) return 0; u=ch[u][c]; cur+=val[u]; } return cur; } }; Trie trie; int main() { trie.Init(); int q; scanf("%d",&q); getchar(); while(q--) { char s[2]; char x[20]; scanf("%s%s",s,x); //cout<<"x="<<x<<endl; if(s[0]=='+') trie.Insert(x,1); if(s[0]=='?') printf("%d\n",trie.Find(x)); if(s[0]=='-') trie.Insert(x,-1); } return 0; }
## Problem D
题意:
题意:录入n个数,c为临界值,如果n个数中相邻的相减小于c就记录如果有一次不满足就删去前面记录的数,最后输出屏幕上存了几个数。
题解:
题意:录入n个数,c为临界值,如果n个数中相邻的相减小于c就记录如果有一次不满足就删去前面记录的数,最后输出屏幕上存了几个数。
C++版本一
#include <bits/stdc++.h> using namespace std; const int N = 5000000+10; int a[N]; int main(int argc, char const *argv[]) { int n , k; cin >> n >> k ; long long sum = 0; for(int i = 1;i <= n ;i ++){ int x; //cin >> x; cin >> a[i]; if(a[i] - a[i - 1] > k) sum = 0; sum ++; } cout << sum << endl; return 0; }
## Problem E
题意:
题目要求的是输出全部字符串!不是满足条件的子串!!
题解:
从前往后暴力搜索满足条件的即可,依次搜26个字母。
当然如果总长度小于26肯定输出-1。
最后处理好?的填充处理就行了。
C++版本一
#include <bits/stdc++.h> using namespace std; const int N = 5000000+10; int a[N]; int vis[30]; char str[1000005]; int main(int argc, char const *argv[]) { //string str; cin >> str; int n = strlen(str); int i = 0 ; if(n < 26) { printf("-1\n"); return 0; } bool flag = 1; for(int i = 0;i <= n - 26 && flag; i ++){ int tail1 = 0 , tail2 = 0; memset(vis,0,sizeof vis); for(int j = i;j < i + 26 ;j ++){ if(str[j] >= 'A' && str[j] <= 'Z'){ // cout << str[j] - 'A' << " " << j - i << endl; vis[str[j] - 'A'] ++; }else tail2 ++; // if(j = i + 25) break; } for(int j = 0;j < 26;j ++){ if(vis[j] == 1) tail1 ++; } if(tail1 + tail2 == 26){ int t = 0; for(int j = i;j < i + 26;j ++){ if(str[j] == '?'){ for(;t < 26;t ++){ if(vis[t] == 0){ str[j] = 'A' + t; t++; break; } } } } flag = 0; } //if(flag) } for(int i = 0;i < n;i ++){ if(str[i] == '?'){ str[i] = 'A'; } } if(flag) cout << -1 << endl; else cout << str << endl; return 0; }
## Problem F
题意:
题意:开始给你个数x=2,然后等级k为1,然后开始加等级k,如果x是完全平方数并且开方后是k+1的倍数,就对x开方,然后等级增加一级,问每升高一级需要加多少次
题解:
找规律
等级k 初始数字 加的次数*等级k 得到x 开根号后的x 关系
√x / (k+1) = k
1 2 +2 * 1 4 2 2 / 2 = 1
2 2 +17 * 2 36 6 6 / 3 = 2
3 6 +46 * 3 144 12 12 / 4 = 3
4 12 +97 * 4 400 20 20 / 5 = 4
所以可以得到关系递推式:
(k-1)*k + k*n = ( k*(k+1))²
上一级开根 次数*等级 新的完全平方数x
号得到的x
所以每次所需要加的次数n =( (k*(k+1))² - (k-1)*k)/k = k*(k+1)² - (k-1)
C++版本一
#include <bits/stdc++.h> using namespace std; const int N = 5000000+10; int a[N]; int vis[30]; char str[1000005]; int main(int argc, char const *argv[]) { long long n ; cin >> n ; if(n == 1){ cout << "2" << endl; } else{ //int ans = 2; cout << "2" << endl; //3int k = 2; for(long long i = 2;i <= n ;i ++){ cout << (i * (i + 1)*(i+1) - i + 1) << endl; // k = sqrt(k * (i + 1) + 1); // ans ++; } } return 0; }