2020.7.10【算协集训】C++基础

网页链接:传送门
密码:handsomeboy
(下面A-E详细点,因为要给算协の学弟学妹们继承(?)下去。为啥CSDN写着写着光标会到前面啊。。写的好累都不太想用它了)

A - A + B Problem II (HDU - 1002)

I have a very simple problem for you. Given two integers A and B, your job is to calculate the Sum of A + B.
Input
The first line of the input contains an integer T(1<=T<=20) which means the number of test cases. Then T lines follow, each line consists of two positive integers, A and B. Notice that the integers are very large, that means you should not process them by using 32-bit integer. You may assume the length of each integer will not exceed 1000.
Output
For each test case, you should output two lines. The first line is “Case #:”, # means the number of the test case. The second line is the an equation “A + B = Sum”, Sum means the result of A + B. Note there are some spaces int the equation. Output a blank line between two test cases.

Sample InputSample Output
2
1 2
112233445566778899 998877665544332211
Case 1:
1 + 2 = 3

Case 2:
112233445566778899 + 998877665544332211 = 1111111111111111110

分析

这道题的题意非常简单(俗话说:越简单的可能是越难的):先输入一个数 T T T ,表示有 T T T 组输入数据,每组数据输入两个数—— A A A B B B ,输出 A + B A+B A+B 的值。

大家的第一个反应应该都是觉得这题可简单,直接加一下输出就完事儿,然而这道题没那么简单!
题目中有一句“You may assume the length of each integer will not exceed 1000.”,你可以假设每个整数的长度不超过 1000 1000 1000 。但长度不超 1000 1000 1000 也很长了!
如果还是不清楚它到底有多长,可以举例子看一下:

类型范围位数
int-2147483648 ~ 21474836479
long long-9223372036854775808 ~ 922337203685477580719
float+/- 3.4e ~ +/- 387
double+/- 1.7e ~ +/- 30815
char0 ~ 255
string

发现了吗!可以说是最常用数据类型的" l o n g long long l o n g long long "也不过 19 19 19 位而已!换句话说: l o n g long long l o n g long long 能存的数据的长度最多只有 19 19 19
知道了这一点,再过来看题目中的 长度不超 1000 1000 1000,就可以明白它有多大了吧!
既然连 l o n g long long l o n g long long 都没有办法,我们不得不放弃原先想的那种简单粗暴的做法,转而利用字符串来进行每一位的相加。这就是这道题需要用字符串的原因,即数据过大。

知道了这道题应该用字符串,那么我们应该怎么使用呢?我们先以A=123,B=45678为例:
A正常人想法
我们平常做这种数学题的时候,就是每位相加计算的。也就是从个位开始,一直计算到两数中最高的那一位(比如这里举的例子是 45678 45678 45678 的长度比 123 123 123 的长度长,而 45678 45678 45678 的最高位是 4 4 4 的位置,即万位,因此我们要计算到万位)。

这对于我们来说很容易理解,但是计算机就傻住了,你要让我咋整噻??你可能不明白为啥计算机它呆住了,还是上面的例子,字符串 A A A 存放的是 123 123 123 ,字符串 B B B 存放的是 45678 45678 45678 ,这是没问题的,可是问题是,我们咋让它一一对应相加呢?可能有人会觉得,先做 A [ 2 ] + B [ 4 ] = 11 A[2]+B[4]=11 A[2]+B[4]=11 ,然后取 11 % 10 = 11\%10= 11%10= 1 1 1,进位是 11 / 10 = 11/10= 11/10= 1 1 1 ;再做 A [ 1 ] + B [ 3 ] + A[1]+B[3]+ A[1]+B[3]+进位的 1 = 10 1=10 1=10 ,然后取 10 % 10 = 10\%10= 10%10= 0 0 0,进位 10 / 10 = 10/10= 10/10= 1 1 1 ;再做 A [ 0 ] + B [ 2 ] + A[0]+B[2]+ A[0]+B[2]+进位的 1 = 8 1=8 1=8 ,然后取 8 % 10 = 8\%10= 8%10= 8 8 8 ,进位 8 / 10 = 8/10= 8/10= 0 0 0;之后就直接是 B [ 1 ] B[1] B[1] B [ 0 ] B[0] B[0] 就好了。可能乍一看没什么问题,可是,这个可以正确只是因为我们的数据正好是这样的而已,如果数据是 1 + 1234567890 1+1234567890 1+1234567890 ,或者是 1234567890 + 12345678901234567890 1234567890+12345678901234567890 1234567890+12345678901234567890 等等奇怪的数字呢?难道都要一个个分析吗?这里我想告诉你:可以,但没必要!长时间的意义很小甚至是无意义的分析,比不上寻找另一种可行的解法。
⚠注意:以下使用的变量不是一定要取这个名字,按自己的喜好(最好是有意义的取法)就可以~
首先,判断A和B的长度是否一致,然后取较大的那个长度存放到 l e n m a x lenmax lenmax 中,然后,我们把 A A A B B B 倒过来,分别存放到数组 a a a 和数组 b b b 中。如下图所示:
A翻转

可能会疑惑为啥要倒过来,看看下一步操作再说!
下一步:把长度没有到 l e n m a x lenmax lenmax 的那个字符串对应的数组后面补齐0。如图:
A翻转补零

这样就避免了上面我们讲的要考虑很多的情况,只需要把短的那个补齐就行,之后就方便一个个对应计算了。

加法比较好做,大家应该都会,如我这设了数组 c c c 存放最后要输出的数据。 A A A B B B 的每位相加的时候,还需要加上前一组数据的进位值,并计算这次数据的进位值以便下一位的计算。就是代码:

		for(i=0;i<lenmax;i++)
		{
			sum=a[i]+b[i]+jin;
			c[i]=sum%10;
			jin=sum/10;
		}

然后这里又会出现一个问题,我们换一组数据举例:A=9000,B=9000
按照我们上面所说的方法:
A9000

但是这里就出现问题了,如果按照我们刚刚的代码,前三个 0 0 0 不用说,那数组 c c c 中存放的铁定是 0 0 0 ,可是当我们的 i i i 已经处在结尾 i = l e n m a x − 1 = 3 i=lenmax-1=3 i=lenmax1=3 的时候, s u m = 18 , c [ 3 ] = 8 , j i n = 1 sum=18,c[3]=8,jin=1 sum=18,c[3]=8,jin=1 ,如果后面没有处理的话,这个进位的 1 1 1 就会白白丢失掉。因此我们在结束循环之后,还需要判断是否还有进位了,如果有的话,就需要再把进位的值放进去,再在后面输出。

那么,字符数字怎么转换成整型数据呢?这里有一些“神奇”操作:

int x=48;	//0的ASCII码值
printf("%c",x);	//输出的是0
char y='0';
printf("%d",y);	//输出的是48

因此字符转换的时候,可以利用 A S C I I ASCII ASCII 码值进行转换。如:

char x='1';	//字符'1'想转换成整型1
int ux=x-'0';	//或者也可以写成x-48
char y='1';	//字符'1'想转换成字符'b'
char uy=y+'a';	//或者也可以写成y+97
char z='1';	//字符'1'想转换成字符'B'
char uz=z+'A';	//或者也可以写成z+65

这里我们只要用到字符转换成整型数据就可以了,但是还是要学会融会贯通。

代码

#include<iostream>	//cin、cout的头文件
#include<cstring>	//memset的头文件
#include<string>
#include<algorithm>
using namespace std;
const int N=1010;
int T,cnt,lena,lenb,lenmax;
string A,B;
int a[N],b[N],c[N],i,sum,jin;
int main()
{
	cin>>T;
	cnt=1;
	while(T--)	//有T组输入
	{
		cin>>A>>B;
		lena=A.size();
		lenb=B.size();
		lenmax=max(lena,lenb);
		memset(a,0,sizeof(a));	//a数组初始化,每个元素的值都是0
		memset(b,0,sizeof(b));	//b数组初始化,每个元素的值都是0
		memset(c,0,sizeof(c));	//c数组初始化,每个元素的值都是0
		for(i=lena-1;i>=0;i--)	//字符串A倒过来存(不够的地方不用单独补零,因为上面已经赋成0了)
			a[lena-i-1]=A[i]-'0';
		for(i=lenb-1;i>=0;i--)	//字符串B倒过来存(不够的地方不用单独补零,因为上面已经赋成0了)
			b[lenb-i-1]=B[i]-'0';
		for(i=0;i<lenmax;i++)	//计算
		{
			sum=a[i]+b[i]+jin;
			c[i]=sum%10;
			jin=sum/10;
		}
		if(jin>0)	//如果计算完了还有一个进位
		{
			c[i]=jin;
			i++;
		}
		cout<<"Case "<<cnt<<":"<<endl;	//endl的意思与"\n"一样,都是换行
		cout<<A<<" + "<<B<<" = ";
		for(int j=i-1;j>=0;j--)
			cout<<c[j];
		cout<<endl;
		if(T!=0)	cout<<endl;//因为题目中有"Output a blank line between two test cases这句话,所以需要再换行一下
		cnt++;
	}
	return 0;
}

B - 进制转换 (HDU - 2031)

输入一个十进制数N,将它转换成R进制数输出。
Input
输入数据包含多个测试实例,每个测试实例包含两个整数N(32位整数)和R(2<=R<=16, R<>10)。
Output
为每个测试实例输出转换后的数,每个输出占一行。如果R大于10,则对应的数字规则参考16进制(比如,10用A表示,等等)。

Sample InputSample Output
7 2
23 12
-4 3
111
1B
-11

分析

这里需要先知道进制是怎么转换的。正好题目中的 N N N 是十进制数,那么这题就变成了十进制数是怎么转换成 R R R 进制数的。

以十进制数转换成二进制和十六进制数为例:(这里取 N = 53 N=53 N=53
B进制转换

  • 对于二进制来说:

    N / R = N/R= N/R= 26 26 26 N % R = N\%R= N%R= 1 1 1

    ( N / R ) / R = (N/R)/R= (N/R)/R= 13 13 13 ( N / R ) % R = (N/R)\%R= (N/R)%R= 0 0 0

    ( ( N / R ) / R ) / R = ((N/R)/R)/R= ((N/R)/R)/R= 6 6 6 ( ( N / R ) / R ) ((N/R)/R)%R= ((N/R)/R) 1 1 1

    … \dots (以此类推,直到 N / N/ N/好几个 R R R 的值为 0 0 0 时结束)

  • 对于十六进制来说:

    N / R = N/R= N/R= 3 3 3 N % R = N\%R= N%R= 5 5 5

    ( N / R ) / R = (N/R)/R= (N/R)/R= 0 0 0 ( N / R ) % R = (N/R)\%R= (N/R)%R= 3 3 3

我们可以发现:循环过程中需要存放 N % R N\%R N%R 的值,循环的结束条件是 N N N 0 0 0 ,循环结束后需要倒过来输出之前存放的数据。

需要单独拎出来讲的是 R > 10 R>10 R>10 时的情况。如果 R > 10 R>10 R>10 ,有可能 N N%R N 得到的值是 > 10 >10 >10 的数,对于这些数,题目要求参考十六进制的写法( 10 10 10 A A A 11 11 11 B B B ,……),这里就需要用到上一题结尾我讲的那个方法。不过与上一题我讲的那个有一点区别是,上一题我是把 1 1 1 转换成 A A A ,而这题是把 11 11 11 转换成 A A A ,二者仅差一个 10 10 10 而已。务必要学会融会贯通!

由此我们可以写出以下代码:

代码

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=1000;
int N,R,a[maxn];
int main()
{
	while(~scanf("%d%d",&N,&R))
	{
		memset(a,0,sizeof(a));
		if(N<0)	//先判断一下十进制数N是否是负数
		{
			printf("-");	//如果是负数先打印负号
			N=-N;	//把十进制数N整成正数以便进行后续的计算
		}
		int i=0;
		while(N)
		{
			a[i]=N%R;
			N/=R;
			i++;
		}
		if(R<=10)	//如果R<=10(十进制数转换成十进制数还是它自己)
		{
			for(int j=i-1;j>=0;j--)
				printf("%d",a[j]);
			printf("\n");
		}
		else	//如果R>10,要考虑余数>10的情况
		{
			for(int j=i-1;j>=0;j--)
			{
				if(a[j]<10)
					printf("%d",a[j]);
				else
					printf("%c",a[j]+'A'-10);	//写成a[j]+55也可以
			}
			printf("\n");
		}
	}
	return 0;
}

C - Palindromes _easy version (HDU - 2029)

“回文串”是一个正读和反读都一样的字符串,比如“level”或者“noon”等等就是回文串。请写一个程序判断读入的字符串是否是“回文”。
Input
输入包含多个测试实例,输入数据的第一行是一个正整数n,表示测试实例的个数,后面紧跟着是n个字符串。
Output
如果一个字符串是回文串,则输出"yes",否则输出"no".

Sample InputSample Output
4
level
abcde
noon
haha
yes
no
yes
no

分析

这题是要判断输入的字符串是否是回文串,而这道题有非常多的解法,这里仅举出两种解法。

第一种解法

回文串只有两种情况:①长度为奇数;②长度为偶数。我们分别探讨一下:

  • 字符串长度为奇数时:
    C第一种写法奇数
    我们可以发现, s t r [ l e n / 2 ] str[len/2] str[len/2] 不与其他数比较, i ∈ [ 0 , l e n / 2 ) i∈[0,len/2) i[0,len/2) 时, s t r [ i ] str[i] str[i] s t r [ l e n − 1 − i ] str[len-1-i] str[len1i] 进行比较,看看是否相等。如果有至少一次不相等,那它就不是回文串;反之,如果没有一次不相等,那它就是回文串。
    (上面的结论是找规律的出来的,比较难说清楚是怎么想的,所以需要自己思考一下)
  • 字符串长度为偶数时
    C第一种写法偶数
    与奇数仅有的区别就是偶数所有数都需要与其他数进行比较。但是我们还是可以发现,此时 l e n / 2 = 3 len/2=3 len/2=3 ,我们还是可以让 i ∈ [ 0 , l e n / 2 ) i∈[0,len/2) i[0,len/2),让 s t r [ i ] str[i] str[i] s t r [ l e n − 1 − i ] str[len-1-i] str[len1i] 进行比较,看看是否相等。如果有至少一次不相等,那它就不是回文串;反之,如果没有一次不相等,那它就是回文串。

如果你觉得自己搞不清楚这个规律,也没有办法找出这个规律,这里还有第二种解法:

第二种解法

第二种解法比较简单粗暴。题目要的不是回文串嘛?回文串的意思就是正着看反着看都一样,那我们就把它反过来,存到一个新的数组中,再让新的数组与老的数组进行比较,看看是否相等。如果相等就说明输入的字符串是回文串,反之就不是。

代码

第一种解法

  1. C + + C++ C++ 写法

    #include<iostream>
    #include<cstring>
    using namespace std;
    int n,len,flag;
    string str;
    int main()
    {
    	cin>>n;
    	while(n--)
    	{
    		cin>>str;
    		len=str.size();	//字符串的长度
    		flag=1;
    		for(int i=0;i<len/2;i++)
    		{
    			if(str[i]!=str[len-i-1])
    			{
    				flag=0;
    				break;
    			}
    		}
    		if(flag)
    			cout<<"yes"<<endl;
    		else
    			cout<<"no"<<endl;
    	}
    	return 0;
    }
    
  2. 1 1 1 C C C 写法(这里自定义了一个函数,但是可以把这个函数直接放到 m a i n main main 函数中,都是一样的)

    #include<stdio.h>
    #include<string.h>
    int judge(char a[])
    {
    	int m=strlen(a),ret=1,i;
    		for(i=0;i<m/2;i++)
    		{
    			if(a[i]!=a[m-i-1])
    			{
    				ret=0;
    				break;
    			}
    		}
    	return ret;
    }
    int main()
    {
    	int n;
    	char a[100];
    	scanf("%d",&n);
    	while(n--)
    	{
    		scanf("%s",a);
    		if(judge(a))
    		  	printf("yes\n");
    		else
    			printf("no\n");
    	}
    	return 0;
    }
    

第二种解法

这里写的感觉是偏向于 C C C C + + C++ C++ 写法:

#include<cstdio>
#include<cstring>
using namespace std;
int main()
{
    char a[10000],b[10000];
    int n,m,x,j;
	scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
    	memset(a,0,sizeof(a));
    	memset(b,0,sizeof(b));
		scanf("%s",a);
    	m=strlen(a);
    	for(j=0;j<m;j++)
    		b[j]=a[m-1-j];
		if(strcmp(a,b)==0)
			printf("yes\n");
		else
			printf("no\n");
	}
    return 0;
}

D - Magical Bamboos (Gym - 101350D)

In a magical forest, there exists N bamboos that don’t quite get cut down the way you would expect.
Originally, the height of the ith bamboo is equal to hi. In one move, you can push down a bamboo and decrease its height by one, but this move magically causes all the other bamboos to increase in height by one.
If you can do as many moves as you like, is it possible to make all the bamboos have the same height?
Input
The first line of input is T – the number of test cases.
The first line of each test case contains an integer N (1 ≤ N ≤ 105) - the number of bamboos.
The second line contains N space-separated integers hi (1 ≤ hi≤ 105) - the original heights of the bamboos.
Output
For each test case, output on a single line "yes” (without quotes), if you can make all the bamboos have the same height, and “no” otherwise.

Sample InputSample Output
2
3
2 4 2
2
1 2
yes
no

分析

这题的题意是:森林里有 N N N 个竹子,如果你砍了其中一个竹子,它的长度会 − 1 -1 1 ,但是其他的竹子长度会 + 1 +1 +1 ,问你经过一通操作之后所有竹子的长度能否一致。

刚刚看到这一题可能会想,啊要不直接遍历一下所有竹子,让所有竹子长度 − 1 -1 1 ,然后其他竹子长度 + 1 +1 +1 看看最后能不能长度一致。听上去似乎可行,但是可能有竹子不止减了一次 1 1 1 ,更何况这样的写法复杂程度非常高,因此我们需要思考其他方法。

我们要回到题目本质,怎么样的情况才能让竹子的长度一致呢?你会发现有竹子长度 − 1 -1 1 ,有竹子长度 + 1 +1 +1 ,如果让它们按长度大小进行排序,当前遍历到的竹子长度和前一个竹子的长度之差必须要是偶数,才能在这一通 ± 1 ±1 ±1 中最后达到一致。

这里不再举例,有想了解的读者可以自行举例验证。

代码

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=1e5+10;
int T,n,h[N],flag;
int main()
{
	scanf("%d",&T);
	while(T--)
	{
		scanf("%d",&n);
		memset(h,0,sizeof(h));
		flag=1;
		for(int i=0;i<n;i++)
			scanf("%d",&h[i]);
		sort(h,h+n);	//默认从小到大排序
		for(int i=n-1;i>0;i--)
		{
			if((h[i]-h[i-1])%2!=0)
			{
				flag=0;
				break;
			}	
		}
		if(flag)
			printf("yes\n");
		else
			printf("no\n");
	}
	return 0;
}

E - 首字母变大写 (HDU - 2026)

输入一个英文句子,将每个单词的第一个字母改成大写字母。
Input
输入数据包含多个测试实例,每个测试实例是一个长度不超过100的英文句子,占一行。
Output
请输出按照要求改写后的英文句子。

Sample InputSample Output
i like acm
i want to get an accepted
I Like Acm
I Want To Get An Accepted

分析

这题也有不少解法,这里只举一例。

我们在接收了输入的字符串后,先让特殊的首字母大写,然后就只需要遍历整个字符串,当遇到空格时,就把空格后面的字母变成大写的,直至遍历结束。

当然还可以先记录每个单词的首字母下标,等到遇到空格的时候把之前存放的该空格前的那个单词的首字母变成大写,直至遍历结束。

还有很多很多种方法等待解锁哟 😀

小写 a a a A S C I I ASCII ASCII 码是 97 97 97 ,大写 A A A A S C I I ASCII ASCII 码是 65 65 65 ,二者相差 32 32 32 ,因此小写字母转换成大写字母仅需要减去 32 32 32 就可以了。

代码

#include<cstdio>
#include<string.h>
using namespace std;
const int N=111;
char str[N];
int len;
int main()
{
	while(gets(str))
	{
		str[0]-=32;	//如果没有记住32,也可以写成'a'-'A'等类似写法
		len=strlen(str);
		for(int i=1;i<len;i++)
		{
			if(str[i]==' ')
				str[i+1]-=32;
		}
		printf("%s\n",str);
	}
	return 0;
}

F - Food Buying (CodeForces - 1296B)

Mishka wants to buy some food in the nearby shop. Initially, he has s burles on his card.
Mishka can perform the following operation any number of times (possibly, zero): choose some positive integer number 1≤x≤s, buy food that costs exactly x burles and obtain ⌊x10⌋ burles as a cashback (in other words, Mishka spends x burles and obtains ⌊x10⌋ back). The operation ⌊ab⌋ means a divided by b rounded down.
It is guaranteed that you can always buy some food that costs x for any possible value of x.
Your task is to say the maximum number of burles Mishka can spend if he buys food optimally.
For example, if Mishka has s=19 burles then the maximum number of burles he can spend is 21. Firstly, he can spend x=10 burles, obtain 1 burle as a cashback. Now he has s=10 burles, so can spend x=10 burles, obtain 1 burle as a cashback and spend it too.
You have to answer t independent test cases.
Input
The first line of the input contains one integer t(1≤t≤104) — the number of test cases.
The next t lines describe test cases. Each test case is given on a separate line and consists of one integer s (1≤s≤109) — the number of burles Mishka initially has.
Output
For each test case print the answer on it — the maximum number of burles Mishka can spend if he buys food optimally.

Sample InputSample Output
6
1
10
19
9876
12345
1000000000
1
11
21
10973
13716
1111111111
#include<cstdio>
using namespace std;
int T;
long long s,t,sum;
int main()
{
	scanf("%d",&T);
	while(T--)
	{
		scanf("%lld",&s);
		sum=0;
		while(s)
		{
			t=s/10;
			sum=sum+t*10;
			s=s-t*10;
			s=s+t;
			if(s<10)
			{
				sum+=s;
				break;
			}
		}
		printf("%d\n",sum);
	}
	return 0;
}

G - Yet Another Walking Robot (CodeForces - 1296C)

There is a robot on a coordinate plane. Initially, the robot is located at the point (0,0). Its path is described as a string s of length n consisting of characters ‘L’, ‘R’, ‘U’, ‘D’.
Each of these characters corresponds to some move:
‘L’ (left): means that the robot moves from the point (x,y) to the point (x−1,y);
‘R’ (right): means that the robot moves from the point (x,y) to the point (x+1,y);
‘U’ (up): means that the robot moves from the point (x,y) to the point (x,y+1);
‘D’ (down): means that the robot moves from the point (x,y) to the point (x,y−1).
The company that created this robot asked you to optimize the path of the robot somehow. To do this, you can remove any non-empty substring of the path. But this company doesn’t want their customers to notice the change in the robot behavior. It means that if before the optimization the robot ended its path at the point (xe,ye), then after optimization (i.e. removing some single substring from s) the robot also ends its path at the point (xe,ye).
This optimization is a low-budget project so you need to remove the shortest possible non-empty substring to optimize the robot’s path such that the endpoint of his path doesn’t change. It is possible that you can’t optimize the path. Also, it is possible that after the optimization the target path is an empty string (i.e. deleted substring is the whole string s).
Recall that the substring of s is such string that can be obtained from s by removing some amount of characters (possibly, zero) from the prefix and some amount of characters (possibly, zero) from the suffix. For example, the substrings of “LURLLR” are “LU”, “LR”, “LURLLR”, “URL”, but not “RR” and “UL”.
You have to answer t independent test cases.
Input
The first line of the input contains one integer t(1≤t≤1000) — the number of test cases.
The next 2t lines describe test cases. Each test case is given on two lines. The first line of the test case contains one integer n (1≤n≤2⋅105) — the length of the robot’s path. The second line of the test case contains one string s consisting of n characters ‘L’, ‘R’, ‘U’, ‘D’ — the robot’s path.
It is guaranteed that the sum of n over all test cases does not exceed 2⋅105 (∑n≤2⋅105).
Output
For each test case, print the answer on it. If you cannot remove such non-empty substring that the endpoint of the robot’s path doesn’t change, print -1. Otherwise, print two integers l and r such that 1≤l≤r≤n — endpoints of the substring you remove. The value r−l+1 should be minimum possible. If there are several answers, print any of them.

Sample InputSample Output
4
4
LRUD
4
LURD
5
RRUDU
5
LLDDR
1 2
1 4
3 4
-1
#include<iostream>
#include<cstring>
#include<map>
#include<utility>
using namespace std;
const int N=2e5+10;
int T,n,len,l,r,x,y;
map<pair<int,int>,int> mp;
long long s,t,sum;
string str;
int main()
{
	cin>>T;
	while(T--)
	{
		cin>>n>>str;
		len=str.size();
		x=y=0;
		l=0,r=n;
		mp.clear();
		mp[{x,y}]=1;
		for(int i=0;i<len;i++)
		{
			if(str[i]=='L')	x--;
			if(str[i]=='R')	x++;
			if(str[i]=='U')	y++;
			if(str[i]=='D')	y--;
			if(mp[{x,y}]!=0 && r-l+1>i+1-mp[{x,y}]+1)
			{
				l=mp[{x,y}];
				r=i+1;
			}
			mp[{x,y}]=i+2;
		}
		if(l==0)
			cout<<-1<<endl;
		else
			cout<<l<<" "<<r<<endl;
	}
	return 0;
}

H - Non-zero (CodeForces - 1300A)

Guy-Manuel and Thomas have an array a of n integers [a1,a2,…,an]. In one step they can add 1 to any element of the array. Formally, in one step they can choose any integer index i (1≤i≤n) and do ai:=ai+1.
If either the sum or the product of all elements in the array is equal to zero, Guy-Manuel and Thomas do not mind to do this operation one more time.
What is the minimum number of steps they need to do to make both the sum and the product of all elements in the array different from zero? Formally, find the minimum number of steps to make a1+a2+… +an≠0 and a1⋅a2⋅ … ⋅an≠0.
Input
Each test contains multiple test cases.
The first line contains the number of test cases t(1≤t≤103). The description of the test cases follows.
The first line of each test case contains an integer n(1≤n≤100) — the size of the array.
The second line of each test case contains n integers a1,a2,…,an (−100≤ai≤100) — elements of the array .
Output
For each test case, output the minimum number of steps required to make both sum and product of all elements in the array different from zero.

Sample InputSample Output
4
3
2 -1 -1
4
-1 0 0 1
2
-1 2
3
0 -2 1
1
2
0
2
#include<cstdio>
#include<cstring>
using namespace std;
const int N=111;
int T,n,a[N],sum,pro,num;
int main()
{
	scanf("%d",&T);
	while(T--)
	{
		scanf("%d",&n);
		sum=pro=num=0;
		for(int i=0;i<n;i++)
		{
			scanf("%d",&a[i]);
			sum+=a[i];
			if(a[i]==0)
				pro+=1;
		}
		num+=pro;
		sum+=pro;
		if(sum==0)
		{
			sum++;
			num++;
		}
		printf("%d\n",num);
	}
	return 0;
}

I - Assigning to Classes (CodeForces - 1300B)

Reminder: the median of the array [a1,a2,…,a2k+1] of odd number of elements is defined as follows: let [b1,b2,…,b2k+1] be the elements of the array in the sorted order. Then median of this array is equal to bk+1.
There are 2n students, the i-th student has skill level ai. It’s not guaranteed that all skill levels are distinct.
Let’s define skill level of a class as the median of skill levels of students of the class.
As a principal of the school, you would like to assign each student to one of the 2 classes such that each class has odd number of students (not divisible by 2). The number of students in the classes may be equal or different, by your choice. Every student has to be assigned to exactly one class. Among such partitions, you want to choose one in which the absolute difference between skill levels of the classes is minimized.
What is the minimum possible absolute difference you can achieve?
Input
Each test contains multiple test cases. The first line contains the number of test cases t(1≤t≤104). The description of the test cases follows.
The first line of each test case contains a single integer n (1≤n≤105) — the number of students halved.
The second line of each test case contains 2n integers a1,a2,…,a2n (1≤ai≤109) — skill levels of students.
It is guaranteed that the sum of n over all test cases does not exceed 105.
Output
For each test case, output a single integer, the minimum possible absolute difference between skill levels of two classes of odd sizes.

Sample InputSample Output
3
1
1 1
3
6 5 4 1 2 3
5
13 4 20 13 2 5 8 3 17 16
0
1
5
#include<cstdio>
#include<algorithm>
using namespace std;
const int N=2e5+10;
int t,n,a[N];
int main()
{
	scanf("%d",&t);
	while(t--)
	{
		scanf("%d",&n);
		for(int i=0;i<2*n;i++)
			scanf("%d",&a[i]);
		sort(a,a+2*n);
		printf("%d\n",a[n]-a[n-1]);
	}
	return 0;
}

J - Display The Number (CodeForces - 1295A)

You have a large electronic screen which can display up to 998244353 decimal digits. The digits are displayed in the same way as on different electronic alarm clocks: each place for a digit consists of 7 segments which can be turned on and off to compose different digits. The following picture describes how you can display all 10 decimal digits:
J
As you can see, different digits may require different number of segments to be turned on. For example, if you want to display 1, you have to turn on 2 segments of the screen, and if you want to display 8, all 7 segments of some place to display a digit should be turned on.
You want to display a really large integer on the screen. Unfortunately, the screen is bugged: no more than n segments can be turned on simultaneously. So now you wonder what is the greatest integer that can be displayed by turning on no more than n segments.
Your program should be able to process t different test cases.
Input
The first line contains one integer t(1≤t≤100) — the number of test cases in the input.
Then the test cases follow, each of them is represented by a separate line containing one integer n(2≤n≤105) — the maximum number of segments that can be turned on in the corresponding testcase.
It is guaranteed that the sum of n over all test cases in the input does not exceed 105.
Output
For each test case, print the greatest integer that can be displayed by turning on no more than n segments of the screen. Note that the answer may not fit in the standard 32-bit or 64-bit integral data type.

Sample InputSample Output
2
3
4
7
11
#include<cstdio>
#include<cstring>
using namespace std;
int T,n;
int main()
{
	scanf("%d",&T);
	while(T--)
	{
		scanf("%d",&n);
		if(n%2==1)
		{
			printf("7");
			n=n-3;
			while(n)
			{
				printf("1");
				n=n-2;
			}
		}
		else
		{
			while(n)
			{
				printf("1");
				n=n-2;
			}
		}
		printf("\n");
	}
	return 0;
}

K - Yet Another Meme Problem CodeForces - 1288B

Try guessing the statement from this picture http://tiny.cc/ogyoiz.
You are given two integers A and B, calculate the number of pairs (a,b) such that 1≤a≤A, 1≤b≤B, and the equation a⋅b+a+b=conc(a,b) is true; conc(a,b) is the concatenation of a and b (for example, conc(12,23)=1223, conc(100,11)=10011). a and b should not contain leading zeroes.
Input
The first line contains t (1≤t≤100) — the number of test cases.
Each test case contains two integers A and B (1≤A,B≤109).
Output
Print one integer — the number of pairs (a,b) such that 1≤a≤A, 1≤b≤B, and the equation a⋅b+a+b=conc(a,b) is true.
Note
There is only one suitable pair in the first test case: a=1, b=9 (1+9+1⋅9=19).

Sample InputSample Output
3
1 11
4 2
191 31415926
1
0
1337
#include<cstdio>
using namespace std;
int t;
long long A,B,sum;
int main()
{
	scanf("%d",&t);
	while(t--)
	{
		scanf("%lld%lld",&A,&B);
		sum=0;
        if(B<9)
            printf("0\n");
        else
		{
            if(B<99)
                printf("%lld\n",A);
            else if(B<999)
                printf("%lld\n",2*A);
            else if(B<9999)
                printf("%lld\n",3*A);
            else if(B<99999)
                printf("%lld\n",4*A);
            else if(B<999999)
                printf("%lld\n",5*A);
            else if(B<9999999)
                printf("%lld\n",6*A);
            else if(B<99999999)
                printf("%lld\n",7*A);
            else if(B<999999999)
                printf("%lld\n",8*A);
            else
                printf("%lld\n",9*A);
        }
	}
	return 0;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值