ecjtu2020训练赛(2) 解题报告

A题 CF22A Second Order Statistics

大水题:
找到数组中第二小的数,排个序找就好了,注意排完序之后要去重
比如 1 1 2 3,答案其实是第3个数

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;
}

B题 CF9A Die Roll

骰子能投出的分数范围是[1, 6],题目给出小Y和小W的分数,问小D获胜的概率:
另 K = max(小Y, 小D)
如果K == 1,那么小D是必胜的,因为就算小D的分数和K相同也算小D胜
如果K > 6 ,那么小D必败
当 1 < K <=6
计算小D获胜的概率,并化简!

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

(这题挺恶心的,写了1个小时。。。。)
因为只能填0或1,可以先列一下前几个数
1,10,11,100,101,110,111……
不难发现它和二进制有着密切的关系
如果111是[1,n]范围内的一个合法数,那么它前面的几个1,10,11,100,101肯定也都可以,而从1~111是很好算的,我们只需要把他当作二进制来看就不难得出,这个个数就是111所代表的10进制数23-1 = 7
所以我们只需要找到[1,n]范围内最大的一个01串,然后把它当作2进制数,将它转换为10进制数后就是答案


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;
}

D题 CF8A Train and Peter

题目的意思是给定一个字符串s0,然后给2个子串s1,s2
问:
1、在s0中是否可以找到s1和s2,并且s2出现在s1之前?(因为s1是先看到的,s2是后看到的),如果可以,输出"forward"
2、然后反转s0,也就是把s0倒过来
然后在问是否可以在s0中找到s1和s2,并且s2出现在s1之前?如果可以,输出"backward"
3、如果两个都可以输出"both"
4、如果s1与s2不合法 或者 找不到这样的子串 就输出"fantasy"

来看看第4个情况如何确定:
首先,Peter中途睡着了,也就是说,他这两次不可能把所有的旗子都看到,所以,如果s1的长度+s2的长度大于s0的长度,那么该情况不合法
还有,如果在s0中找不到s1这样的子串或者s2这样的子串,也不合法

先介绍一个string类型自带的函数,比较方便,也可以自己写一个函数
find函数:
string a,b;

a.find(b) 是在a中查找b,如果找到了,返回b在a中第一次出现的位置,
没找到返回-1
a.find(b,k)是从a的下标为k的地方开始找b,找到了返回b在a中第一次出现的位置,没找到返回-1


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

题目说的很清楚了,而且n比较小,直接枚举每一个站点,注意第一个站点不能当作下车的地方,然后按要求比较大小,留下符合要求的一个

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

这题可以用map来解决,非常方便
不熟悉map的可要好好学学


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;
}

猜你喜欢

转载自blog.csdn.net/m0_50815157/article/details/114092519