无专精|

伍六柒-

园龄:3年6个月粉丝:9关注:6

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),请你找的(l1,r1),(l2,r2), t 为从 s 的第 l1位截取到第r1位所得到的二进制数转换成的十进制数,w 为从 s 的第 l2位截取到第r2位所得到的二进制数转换成的十进制数请你求出(l1,r1),(l2,r2),使得 t = w * k,(k 为非负整数)
输入描述
第一行是一个整数 T 代表有 T 组测试数据
接下来每组数据的第一行时一个整数 n,第二行是二进制数 s
输出描述
对于每组数据,依次输出 l1,r1,l2,r2 中间用空格隔开
如果有很多结果输出任意一个即可
不能同时满足 l1 == l2,r1 == r2
原题链接


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 中国大陆许可协议进行许可。

posted @   伍六柒-  阅读(99)  评论(2编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
展开