ecjtu2020 training competition (2) Problem solving report

A题 CF22A Second Order Statistics

Big water question:
Find the second smallest number in the array and find it in order. Pay attention to the repetition after sorting. For
example, 1 1 2 3, the answer is actually the third number

const int N = 110;

int n, a[N];

int main()
{
    
    
	cin >> n;
	for(int i = 1; i <= n; i++)	cin >> a[i];
	sort(a+1, a+1+n);
	int f = a[1];
	for(int i = 1; i <= n; i++)
	{
    
    
		if(a[i] != f)
		{
    
    
			cout << a[i] << endl;
			return 0;
		}
	}
	cout << "NO" << endl;
	return 0;
}

Question B CF9A Die Roll

The range of scores that can be thrown by the dice is [1, 6]. The question gives the scores of small Y and small W. Ask the probability of small D to win:
another K = max (small Y, small D)
If K == 1, then Small D is sure to win, because even if the score of small D is the same as K, it is considered small D wins.
If K> 6, then small D will lose.
When 1 <K <=6,
calculate the probability of small D winning and simplify!

int main()
{
    
    
	int y, w;
	cin >> y >> w;
	int k =max(y, w);

	if(k > 6)	{
    
     cout << "0/1" << endl; return 0; }
	if(k == 1)	{
    
     cout << "1/1" << endl; return 0; }
	
	int fz = 7 - k;
	int g = __gcd(fz, 6);  // __gcd 是C++库里的一个函数,可以直接用
	cout << fz/g << "/" << 6/g << endl;
	return 0;
}

C题 CF9C Hexadecimal’s Numbers

(This question is disgusting. It took 1 hour to write...)
Because you can only fill in 0 or 1, you can list the first few numbers 1, 10, 11, 100,
101, 110, 111...
not difficult It is found that it has a close relationship with the binary system.
If 111 is a legal number in the range of [1,n], then the previous ones 1,10,11,100,101 are certainly all possible, and it is easy to calculate from 1 to 111. We only need to look at it as a binary system. This number is the decimal number represented by 111. 2 3 -1 = 7,
so we only need to find the largest 01 string in the range of [1,n] , And then treat it as a binary number, and convert it to a decimal number is the answer


int main()
{
    
    
	int n; cin >> n;
	int t = n, s = 0;
	while(t)	s++, t /= 10; //s是计算n有多少位
	
	int res = 0;
	int ten = 1;
	for(int i = 1; i < s; i++)	ten *= 10;
	
	//我们规定个位是第0位,位数是[0,s-1]
	for(int i = s-1; ~i; i--, ten /= 10) 
	{
    
    
		int num = n / ten % 10; //得到n的第i位数
//		cout << num << endl;
		if(num > 1)	{
    
     res += pow(2, i+1)-1; break; } 
		//如果第i为大于2,那么后面的其他所有位都可以填1
		//比如说10200,最大的是10111;
		if(num == 1)	res += pow(2, i);
		//如果第i位为1,就填1,对答案的贡献为2^i
	}
	
	cout << res << endl;
	return 0;
}

Question D CF8A Train and Peter

The question means that given a string s0, then two substrings s1 and s2 are
asked:
1. Can s1 and s2 be found in s0 and s2 appears before s1? (because s1 is seen first, s2 (I saw it later). If you can, output "forward"
2. Then reverse s0, that is, reverse s0
and ask whether you can find s1 and s2 in s0, and s2 appears before s1? If so, Output "backward"
3. If both can output "both"
4. If s1 and s2 are illegal or no such substring can be found, output "fantasy"

Let’s take a look at how the fourth situation is determined:
First, Peter fell asleep halfway through, that is to say, he cannot see all the flags these two times, so if the length of s1 + the length of s2 is greater than the length of s0 , Then the situation is illegal.
Also, if no substring like s1 or s2 is found in s0, it is also illegal

First introduce a function that comes with string type, it is more convenient, you can also write a function
find function yourself :
string a, b;

a.find(b) is to find b in a, if found, return the position of b in a for the first time, if
not found, return -1
a.find(b,k) is from the subscript of a to k Start looking for b in the place where b is found, and return to the first occurrence of b in a, but return -1 if not found


int main()
{
    
    
	string s0, s1, s2;
	cin >> s0 >> s1 >> s2;
	
	if(s1.length()+ s2.length() > s0.length())
	{
    
    
		cout << "fantasy" << endl;	return 0;
	}	
	bool f1 = 0, f2 = 0; //f1判断正着来是否成功,f2是倒着来
	
	int p1 = s0.find(s1);
	int p2 = s0.find(s2, p1 + 1);
//	cout << p1 << " " << p2 << endl;
	if(p1 <= p2) f1 = 1; //s1出现在s2之前
	if(p1 == -1 || p2 == -1)	f1 = 0; //没找到这样的子串
	
	reverse(s0.begin(), s0.end()); //反转s0
	
	p1 = s0.find(s1);
	p2 = s0.find(s2, p1 + 1);
//	cout << p1 << " " << p2 << endl;
	if(p1 <= p2) f2 = 1;
	if(p1 == -1 || p2 == -1)	f2 = 0;
	
	if(f1 && f2)	cout << "both" << endl;
	else	if(f1)	cout << "forward" << endl;
	else	if(f2)	cout << "backward" << endl;
	else	cout << "fantasy" << endl;
	
	return 0;
}

E题 CF9B Running Student

The topic is very clear, and n is relatively small, directly enumerate each site, pay attention to the first site can not be used as a place to get off, then compare the size as required, and leave the one that meets the requirements

int n;
double x[110], fx, fy, vb, vs;

double dis(int i) //计算站点i到(fx,fy)的距离
{
    
    
	double dx = fx - x[i], dy = fy;
	return sqrt(dx * dx + dy * dy);
}

double get(int i) //计算把i当作下车的站点花费的时间
{
    
    
	double t1 = x[i] / vb;
	double t2 = dis(i) / vs;
	return t1 + t2;
}

int main()
{
    
    
	cin >> n >> vb >> vs;
	for(int i = 1; i <= n; i++)	cin >> x[i];
	cin >> fx >> fy;
	
	double T = 1e18, d; //T保留的是最小时间,d是站点res到(fx,fy)的距离
	int res;
	
	for(int i = 2; i <= n; i++) //注意从第二个车站开始枚举
	{
    
    
		double t = get(i);
//		cout << t << endl;
		
		if(t < T)
			res = i, T = t, d = dis(i);
		else if(t == T && dis(i) < d)
			res = i, d = dis(i);
	}
	
	cout << res << endl;
	return 0;
}

F题 CF4C Registration system

This problem can be solved with map, which is very convenient. Those who are
not familiar with map should study hard .


map<string,int> cnt; //cnt记录字符串出现的次数

int main()
{
    
    
	int n; cin >> n;
	string name;
	while(n--)
	{
    
    
		cin >> name;
		if(cnt[name] == 0) //如果name出现的次数为0,表明它是第一次出现
		{
    
    
			cout << "OK" << endl;
			cnt[name]++; //次数+1
		}
		else
		{
    
    
			cout << name << cnt[name] << endl; //输出它是第几次出现
			cnt[name]++; //次数+1
		}
	}
	return 0;
}

Guess you like

Origin blog.csdn.net/m0_50815157/article/details/114092519