Codeforces#741div2
A-The Miracle and the Sleeper
题目描述
给你两个整数 l,r,请你找出所有数对(a,b)中,使得 a % b 结果最大的数对。其中 r >= a >= b >= l
输入描述
每个测试样例有多组数据,第一行会输入一个 t (1<= t <= 1e4),代表数据个数。接下来的每一行,会输入两个整数 l,r (1 <= l <= r <= 1e9)
输出描述
对于每一个测试数据,输出 a % b 的最大值。
原题链接
Input
4 1 1 999999999 1000000000 8 26 1 999999999
Output
0 1 12 499999999
解题思路
对于一个数对(a,b),当 a = 2b - 1时,a % b 的结果最大为 b - 1(此时认为 a 可以为任意值),但题目中 a 最大为 r,所以当 b = r/2 + 1时,能取到最大值,又由于 b 要大于等于 l,所以当 r/2 + 1小于 l 时,就让 b = l 即可,此时增大 b 的值并不会改变结果。
AC代码
#include <iostream> using namespace std; int main(){ int l,r,a,b,t; scanf("%d",&t); while(t--){ scanf("%d %d",&l,&r); a = r,b = r/2 + 1; if(b < l) b = l; cout << a % b << endl; } return 0; }
B-Scenes From a Memory
题目描述
给定一个数(确保每一位数字都不为0),你可以删除其中的任意个数字,删除任意个数字后,得到一个新的数,确保剩下这个数不是质数,请尽可能的删除越多的数字输出剩下的数字。(确保一定有结果)
输入描述
先输入一个整数 t (1 <= t <= 1e3),代表有 t 组测试数据,对于每一组测试数据,第一行输入一个 n (1 <= n <= 50) ,代表接下来输入的数的位数,第二行为输入的数s。
输出描述
对于每一个测试数据,第一行输出这个新的数有几位数,第二行输出这个数
原题链接
Input
7 3 237 5 44444 3 221 2 35 3 773 1 4 30 626221626221626221626221626221
Output
2 27 1 4 1 1 2 35 2 77 1 4 1 6
解题思路
由于位数比较多所以用字符串储存数s,对于给定的数,只要这个数中出现了”1,4,6,8,9“,中的任意一个数字,我们就可以把这个数的其他数字全部删除,只留下这一位。若这个数不含有上面的数字,我们可以统计一下分别出现了多少次“2,3,5,7”,如果其中有一个出现了两次以上,那么我们就保留两个这个数,其他数字删掉。如果没有任何一个数字出现了两次以上,那么 n <= 4 ,就直接dfs(),挨个判断选中的数是不是素数就行了。
AC代码
#include <iostream> #include <cstring> using namespace std; char num[55]; int cnt[11],t,n,value,ans,idx; bool st[4],flag; bool is_prime (int x){ if(x == 1) return false; if(x == 0 || x == 2 || x == 3) return true; if(x % 6 == 5 || x % 6 == 1){ for(int i = 2; i <= x / i; i++) if(x % i == 0) return false; } else return false; return true; } void dfs(int x){ for(int i = x; i < n; i++){ if(!st[i]){ st[i] = true; value = value * 10 + num[i] - '0'; if(!is_prime(value)) ans = min(ans,value); dfs(i+1); value /= 10; st[i] = false; } } } int main(){ scanf("%d",&t); while(t--){ idx = 0,flag = false,value = 0,ans = 10000; memset(cnt,0,sizeof(cnt)); memset(st,false,sizeof(st)); scanf("%d",&n); scanf("%s",&num); for(int i = 0; i < n; i++){ if(num[i] != '2' && num[i] != '3' && num[i] != '5' && num[i] != '7'){ cout << 1 << endl << num[i] << endl; flag = true; break; } cnt[num[i]-'0']++; } if(flag) continue; if(cnt[2] > 1) {cout << 2 << endl << 22 << endl;continue;} if(cnt[3] > 1) {cout << 2 << endl << 33 << endl;continue;} if(cnt[5] > 1) {cout << 2 << endl << 55 << endl;continue;} if(cnt[7] > 1) {cout << 2 << endl << 77 << endl;continue;} dfs(0); int temp = ans; while(temp != 0) temp /= 10,idx++; cout << idx << endl << ans << endl; } return 0; }
C-Rings
题目描述
给你一个长度为 n 的二进制数s,(2 <= n <= 2e4),请你找的(,),(,), t 为从 s 的第 位截取到第位所得到的二进制数转换成的十进制数,w 为从 s 的第 位截取到第位所得到的二进制数转换成的十进制数请你求出(,),(,),使得 t = w * k,(k 为非负整数)
输入描述
第一行是一个整数 T 代表有 T 组测试数据
接下来每组数据的第一行时一个整数 n,第二行是二进制数 s
输出描述
对于每组数据,依次输出 ,,, 中间用空格隔开
如果有很多结果输出任意一个即可
不能同时满足 == , ==
原题链接
Input
7 6 101111 9 111000111 8 10000000 5 11011 6 001111 3 101 30 100000000000000100000000000000
Output
3 6 1 3 1 9 4 9 5 8 1 4 1 5 3 5 1 6 2 4 1 2 2 3 1 15 16 30
解题思路
从二进制串的开始遍历它,找到第一个’0‘出现的位置,标记为 dis, 则 1dis-1这串二进制数,乘2的结果一定等于1dis这段二进制的值,disn的值一定等于dis+1n的值,所以,直接找第一个 0 出现的位置就行(第二个也行),为了使 l,r 的差值大于 n/2-1,判断一下dis于 n/2 大小关系即可,如果dis在前,则往后选,反之则往前选。
AC代码
#include <iostream> using namespace std; int main() { int t,n; string s; bool flag; cin >> t; while(t--) { cin>> n >> s; flag = false; for(int i = 1;i <= n; i++) { if(s[i-1] == '0') { if(i-1 >= n/2) cout << 1 << " " << i << " " << 1 <<" " << i-1 << endl; else cout<< i << " " << n << " " << i+1 << " " << n << endl; flag = 1; break; } } if(flag == 0) cout << 1 << " " << n/2 << " " << 2 << " " << n/2+1 << endl; } }
D1-Two Hundred Twenty One (easy version)
题目描述
给你一个长度 n ,和一个长度为 n 的只有’+‘和’-‘的字符串 str,再给出你一个指令(a,b),从 str 的第 a 个字符串开始到第 b 个字符串求和。求和的方法为:如果str[i] = '+',代表 1,str[i] = '-',代表 -1 。从第 a 位开始数到第str[i],如果是奇数则变号(1变成-1,-1变成1),偶数不变号,累加得到(a,b)的求和结果 sum,如果sum = 0,则不用进行操作,如果不为 0,请你去掉 str 中从 a 到 b 之间的若干个字符,使得 sum = 0。
输入描述
第一行输入整数 t 代表测试样例个数(1 <= t <= 1e3)
第二行先是一个整数 n,再是一个整数 p代表指令条数 (1 <= n,p <= 3e5)
第三行是一个只包含’+‘’-‘的字符串长度为 n
接下来的 p 行每一行有两个整数 a,b。 (1 <= a <= b <= n)
输出描述
请输出使得sum = 0,所需要的操作次数
原题链接
Input
3 14 1 +--++---++-++- 1 14 14 3 +--++---+++--- 1 14 6 12 3 10 4 10 +-+- 1 1 1 2 1 3 1 4 2 2 2 3 2 4 3 3 3 4 4 4
Output
2 2 1 0 1 2 1 2 1 2 1 1 2 1
解题思路
对于给定的str和(a,b),可以求出一个确定的sum,当sum = 0时,不需要任何操作输出 0 即可;当sum奇数时,我们一定可以从(a,b)中找到某个点,使得这个点后面的和等于这个点前面的和,如果我们把这个点去掉,可以发现,这个点后面的和会变成原来的相反数,这个时候,整体和就为 0了;当sum为偶数是,我们可以先去某一个字符,sum就变成了奇数,再按刚刚的方法做就行。(小提示:求和要用前缀和,否则会超时)
AC代码
#include <iostream> #include <cstring> #include <cmath> using namespace std; const int N = 3e5 + 10; int t,n,op,a,b,c; int arr[N]; string str; int main(){ scanf("%d",&t); while(t--){ cin >> n >> op >> str; for(int i = 0; i < n; i++){ if(i % 2 != 0){ if(str[i] == '+') c = 1; else c = -1; } else { if(str[i] == '-') c = 1; else c = -1; } arr[i+1] = arr[i] + c; } for(int i = 0; i < op; i++){ cin >> a >> b; c = arr[b] - arr[a-1]; if(c == 0) puts("0"); else if(c % 2 == 0) puts("2"); else puts("1"); } } return 0; }
本文作者:伍六柒-
本文链接:https://www.cnblogs.com/paper-plane/p/15193256.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步