Educational Codeforces Round 99 (Rated for Div. 2)(详细题意+思路,A-D题)

A. Strange Functions

Let’s define a function f(x) (x is a positive integer) as follows: write all digits of the decimal representation of x backwards, then get rid of the leading zeroes. For example, f(321)=123, f(120)=21, f(1000000)=1, f(111)=111.

Let’s define another function g(x)=xf(f(x)) (x is a positive integer as well).

Your task is the following: for the given positive integer n, calculate the number of different values of g(x) among all numbers x such that 1≤x≤n.

Input
The first line contains one integer t (1≤t≤100) — the number of test cases.

Each test case consists of one line containing one integer n (1≤n<10100). This integer is given without leading zeroes.

Output
For each test case, print one integer — the number of different values of the function g(x), if x can be any integer from [1,n].

Example
inputCopy
5
4
37
998244353
1000000007
12345678901337426966631415
outputCopy
1
2
9
10
26
Note
Explanations for the two first test cases of the example:

if n=4, then for every integer x such that 1≤x≤n, xf(f(x))=1;
if n=37, then for some integers x such that 1≤x≤n, xf(f(x))=1 (for example, if x=23, f(f(x))=23,xf(f(x))=1); and for other values of x, xf(f(x))=10 (for example, if x=30, f(f(x))=3, xf(f(x))=10). So, there are two different values of g(x).

题意: 题目巴拉巴拉一大堆,实际就是让你求字符串的长度。

思路 只要用string直接存下来输出长度就好了。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
string x;
int main()
{
	int t;
	cin>>t;
	while(t--){
		cin>>x;
		printf("%d\n",x.size());
	}
	return 0;
 } 

B. Jumps

You are standing on the OX-axis at point 0 and you want to move to an integer point x>0.

You can make several jumps. Suppose you’re currently at point y (y may be negative) and jump for the k-th time. You can:

either jump to the point y+k
or jump to the point y−1.
What is the minimum number of jumps you need to reach the point x?

Input
The first line contains a single integer t (1≤t≤1000) — the number of test cases.

The first and only line of each test case contains the single integer x (1≤x≤106) — the destination point.

Output
For each test case, print the single integer — the minimum number of jumps to reach x. It can be proved that we can reach any integer point x.

Example
inputCopy
5
1
2
3
4
5
outputCopy
1
3
2
3
4
Note
In the first test case x=1, so you need only one jump: the 1-st jump from 0 to 0+1=1.

In the second test case x=2. You need at least three jumps:

the 1-st jump from 0 to 0+1=1;
the 2-nd jump from 1 to 1+2=3;
the 3-rd jump from 3 to 3−1=2;
Two jumps are not enough because these are the only possible variants:

the 1-st jump as −1 and the 2-nd one as −1 — you’ll reach 0−1−1=−2;
the 1-st jump as −1 and the 2-nd one as +2 — you’ll reach 0−1+2=1;
the 1-st jump as +1 and the 2-nd one as −1 — you’ll reach 0+1−1=0;
the 1-st jump as +1 and the 2-nd one as +2 — you’ll reach 0+1+2=3;
In the third test case, you need two jumps: the 1-st one as +1 and the 2-nd one as +2, so 0+1+2=3.

In the fourth test case, you need three jumps: the 1-st one as −1, the 2-nd one as +2 and the 3-rd one as +3, so 0−1+2+3=4.

题意: 给你一个数x,你有两种操作,一种是在第i次操作的时候加i,一种是在第i次操作的时候减一,问你最少要经过多少操作才能得到x。

思路: 我们只要一直进行操作一,知道它大于数x,那我们发现我们得到的数和差几,就把前面一个加i的操作改成减一就行了,相当于减了i+1.所以我们不管怎么样,都只要操作到大于x的次数。只有一种特殊情况,是当我们得到的数就比x大一时,因为我们改变前面的操作最小可以减二,不能减1,所以要在加一次操作,减一,就行了。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
string x;
int main()
{
	int t;
	cin>>t;
	while(t--){
		int x;
		cin>>x;
		int cnt=0;
		int ans=0;
		while(ans<x){
			ans+=(++cnt);
		}
		if(ans!=x+1)
			printf("%d\n",cnt);
		else
			printf("%d\n",cnt+1);
	}
	return 0;
 } 

C. Ping-pong

Alice and Bob play ping-pong with simplified rules.

During the game, the player serving the ball commences a play. The server strikes the ball then the receiver makes a return by hitting the ball back. Thereafter, the server and receiver must alternately make a return until one of them doesn’t make a return.

The one who doesn’t make a return loses this play. The winner of the play commences the next play. Alice starts the first play.

Alice has x stamina and Bob has y. To hit the ball (while serving or returning) each player spends 1 stamina, so if they don’t have any stamina, they can’t return the ball (and lose the play) or can’t serve the ball (in this case, the other player serves the ball instead). If both players run out of stamina, the game is over.

Sometimes, it’s strategically optimal not to return the ball, lose the current play, but save the stamina. On the contrary, when the server commences a play, they have to hit the ball, if they have some stamina left.

Both Alice and Bob play optimally and want to, firstly, maximize their number of wins and, secondly, minimize the number of wins of their opponent.

Calculate the resulting number of Alice’s and Bob’s wins.

Input
The first line contains a single integer t (1≤t≤104) — the number of test cases.

The first and only line of each test case contains two integers x and y (1≤x,y≤106) — Alice’s and Bob’s initial stamina.

Output
For each test case, print two integers — the resulting number of Alice’s and Bob’s wins, if both of them play optimally.

Example
inputCopy
3
1 1
2 1
1 7
outputCopy
0 1
1 1
0 7
Note
In the first test case, Alice serves the ball and spends 1 stamina. Then Bob returns the ball and also spends 1 stamina. Alice can’t return the ball since she has no stamina left and loses the play. Both of them ran out of stamina, so the game is over with 0 Alice’s wins and 1 Bob’s wins.

In the second test case, Alice serves the ball and spends 1 stamina. Bob decides not to return the ball — he loses the play but saves stamina. Alice, as the winner of the last play, serves the ball in the next play and spends 1 more stamina. This time, Bob returns the ball and spends 1 stamina. Alice doesn’t have any stamina left, so she can’t return the ball and loses the play. Both of them ran out of stamina, so the game is over with 1 Alice’s and 1 Bob’s win.

In the third test case, Alice serves the ball and spends 1 stamina. Bob returns the ball and spends 1 stamina. Alice ran out of stamina, so she can’t return the ball and loses the play. Bob, as a winner, serves the ball in the next 6 plays. Each time Alice can’t return the ball and loses each play. The game is over with 0 Alice’s and 7 Bob’s wins.

题意: 每个人都有x的体力,发球和接球都要消耗一点体力。AA先手,我们要先保证在自己胜利的最多的情况下,使对方胜利的最少。双方都取最优策略,问最后双方各自的胜场数。

思路: 我们发现,对于后手的人来说,它最多赢他的体力场数(先等对面的体力耗到只有一点的时候才开始接球),因为我们要先保证自己的胜场数最大,所以后手的胜场数就是自己的体力数。而对于先手来说,因为后手选择了最优策略,所以先手可以赢下它的体力减一场数,因为最后一场先手发球,后手接球,先手就输了。这时答案就很清晰了,直接输出就好了。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
string x;
int main()
{
	int t;
	cin>>t;
	while(t--){
		int a,b;
		cin>>a>>b;
		printf("%d %d\n",a-1,b);
	}
	return 0;
 } 

D. Sequence and Swaps

题意: 有一个数组,我们有一个数x,我们可以将x和比他大的一个数组种的数进行交换,问最少多少次操作,我们可以得到一个非递减数组。如果不可能输出-1。

思路: 当看见n<=500时,我就发现事情不简单。我们完全可以暴力,把所有情况遍历一遍,然后找出花费步数最小的。我们只要把最终数组可能的存在形式全部都找出来来,然后给它排序。看每个位置的数有没有变化,如果边大就是步数加一,如果变小就是这种情况不存在。最后输出找到的最小值就好了。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int a[1000],c[1000];
struct node{
	int id;
	int dis;
}b[1000],zhuan[1000];
bool cmp(node a,node b){
	return a.dis<b.dis;
}
int main()
{
	int t;
	cin>>t;
	while(t--){
		int n,x;
		cin>>n>>x;
		for(int i=1;i<=n;i++){
			cin>>a[i];
			b[i].dis=a[i];
			b[i].id=i;
		}
		sort(b+1,b+1+n,cmp);
		int cnt=0;
		for(int i=1;i<=n;i++){
			if(b[i].dis>x){
				if(cnt==0){
					zhuan[++cnt].id=b[i].id;
					zhuan[cnt].dis=b[i].dis;
				}else{
					if(b[i].dis>b[i-1].dis){
						zhuan[++cnt].id=b[i].id;
						zhuan[cnt].dis=b[i].dis;
					}
				}
			}
		}
		int minn=-1;
		for(int i=0;i<=cnt;i++){
			for(int j=1;j<=n;j++){
				c[j]=a[j];
			}
			if(i!=0){
				c[zhuan[i].id]=x;	
			}
			sort(c+1,c+1+n);
			int cc=0;
			for(int j=1;j<=n;j++){
				if(c[j]!=a[j]){
					if(c[j]<a[j]){
						cc++;
					}else{
						cc=-1;
						break;
					}
				}
			}
			if(cc!=-1){
				if(minn==-1)minn=cc;
				else minn=min(minn,cc);
			}
		}
		printf("%d\n",minn);
	}
	return 0;
 } 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值