## 弱鸡的第三次线上赛总结(TKK18no.6)(WIP)

一些闲话

这次隔了这么久才更这一次线上赛,其实中间有一丢丢原因,我先在这里甩个锅。其一是上次线上赛没参加(不要和我提转普通练习),去参加了志愿者活动(心中有党);其二是其实这次线上赛也有两题没过,琢磨了半天还是runtime或者memory limit。但想了想还是先把这次的WIP发出来,接受指导与建议。

第一题:字符串替换

把字符串s中的前m个字符c替换成字符串d。
输入一个正整数n,表示测试案例的数量。
每组案例由一个字符串s,一个正整数m,一个字符c,一个字符串d组成。(保证s里至少会有m个c字符)
输出
针对每组案例,输出一个字符串,表示根据描述变化后的字符串。
每组案例输出完都要换行。

没什么好说的,找出来,换一下,输出来。

#include <iostream>
#include<string>
using namespace std;
int main()
{
	int m, n,i;
	string a, b; char c;
	cin >> n;
	while (n--)
	{
		cin >> a >> m >> c >> b;
		for (i = 0; i < a.length(); i++)
		{
			if (a[i] == c&&m!=0)
			{
				cout << b; m--;
			}
			else cout << a[i];
		}
		cout << endl;
	}
}

第二题:大柱的乘法

大柱规定了一种特别的乘法:当两个数相乘时,列竖式计算;如果位数不同,则通过高位补0的方式对齐;运算时,每个数位分开计算,相同数位上下两个数字相乘,取乘积的个位数作为该数位的值。例如:大柱乘法

这道题就按照题意实现即可,依位数补完再相乘即可。

#include<iostream>
#include<string>
#include<cmath>
#include<algorithm>
using namespace std;
int main()
{
	int m, n, k;
	string a, b,t; char c;
	cin >> n;
	while (n--)
	{
		cin >> a >> b; t = "";
		int j = b.length() - 1;
		for (int i = a.length() - 1; i >= 0 ; i--)
		{
			t += char((((a[i] - '0')*(b[j] - '0')) % 10)+'0');
			j--;
			if(j<0)break;
		}
		int k = 0;
		for (int i = t.length() - 1; i >= 0; i--)
		{
			if (t[i] != '0'&&k==0)
			{
				k = 1; cout << t[i];
			}
			else if(k==1) cout << t[i];
		}
		if (k == 0)
			cout << 0;
		cout << endl;
	}
	return 0;
}

第三题:谁是卧底

曹操因为“鸡肋”口令杀了杨修之后,觉得拿某个名词当口令太容易让文官们胡思乱想,所以使用了一个整数当口令,见面时喊这个整数来表明是自己人而不是敌方间谍。然而后来又遇到了个问题,士兵们记性不好,无法准确记住这个整数,于是曹操规定,只要喊的数字能和口令相差10之内(包括10)都算对,这下子所有士兵都能喊出正确范围内的口令。有一天来了个蜀国的间谍混入了士兵中,曹操为了能分清总共m名士兵中,究竟谁是间谍,就让他们各自在纸上写下口令,同时交上来。假设魏国的士兵都各自写出了正确范围内的一个口令,而唯一一个蜀国的间谍是乱写的。这时曹操的头风病犯了,自己不记得口令是多少了,而且曹操生性多疑,不相信别人告诉他的口令。
问:曹操是否有可能根据士兵们交上来的口令,就能明确断定出谁是间谍?
输入
一个正整数n,表示n组案例。
每组案例先是一个正整数m(2<=m<=10000),表示连同间谍在内一共有m名士兵。然后是m个整数,分别表示第1、2、…、m名士兵写的口令。案例保证最多只会有一名间谍。
输出
针对每组案例,如果无法区分谁是间谍,则输出Cannot;如果能找出间谍,则输出间谍是第几个士兵(士兵编号从1到m)。
每组案例输出完都要换行。

关于这道题,其实我是有些疑惑的,比如5,20,20,20,35是不是Cannot,但后来听说好像不需要考虑这种可能。所以就是所有的数快排一下,然后要么最大要么最小,判断哪个是卧底。

#include <iostream>
#include<algorithm>
#include<cmath>
using namespace std;
struct s
{
	int id, num;
};
int main()
{
	int n;
	cin >> n;
	while (n--)
	{
		int m,k;
		cin >> m;
		if (m > 2)
		{
			s x[m];
			for (int i = 0; i < m; i++)
			{
				x[i].id = i + 1;
				cin >> x[i].num;
			}
			for (int i = 1; i < m; i++)
			{
				for (int j = 0; j < i; j++)
				{
					if (x[j].num>x[i].num)
						swap(x[i], x[j]);
				}
			}
			if (x[m - 1].num - x[0].num <= 20)
				cout << "Cannot";
			else
			{
				if (x[m - 1].num - 20 > x[1].num)
					cout << x[m-1].id;
				else cout << x [0].id;
			}
			cout << endl;
		}
		else
		{
			while (m--)
				cin >> k;
			cout << "Cannot" << endl;
		}
	}
	return 0;
}

第四题:货郎担

星星用扁担挑了一摊货去赶集。货物一共有10件,每件货物都有一定的重量。扁担的两边各吊着一个筐,筐中可以装任意多件货物。星星希望两个筐中的货物重量差距尽可能小,以方便挑担时保持平衡。问该重量差距最小是多少?

这道题应该是背包的变形,同时因为案例比较小也可以用dfs做,但是不知道为什么,我就是re转mle。

丢脸,不发代码了。

第五题:字符串出现次数

看看a字符串里出现了多少次b字符串,规定如果多个b字符串在a中的位置出现重叠,则都不计入次数。
例如abababa里计算出现了多少次的aba时,由于所有的aba字符串都存在与别的aba字符串位置重叠,所以一共出现0次。

这个题也比较基础,就是找出来b字符串后把他的位置存好,和后一个比较是否小于b的长度。

#include<iostream>
#include<string>
using namespace std;
int main()
{
	int n;
	cin>>n;
	while(n--)
	{
		string a,b;
		cin>>a>>b;
		int B=b.length();
		int r=-B-1;
		int sum=0;
		for(int i=0;i<a.length();i++)
		{
			if(a.substr(i,B)==b)
			{
				if(sum==1&&i-r<B)
			    {
			    	sum--;
				}
				if(i-r>=B)
				{
					sum=sum+1;
			    }
			    r=i; 
			}
		}
		cout<<sum<<endl;
	}
}

第六题:三英战大柱

有m个勇敢的学弟想要线下赛组队挑战大柱,规则上至多只允许3个学弟组队。黄大佬作为学弟的精神领袖,想要暗地帮助学弟组队,以达到最好的效果,即把所有题目都做出来。这m个学弟分别把所有题目的解题思路告诉了黄大佬,黄大佬记下了每个学弟按照解题思路是否可以做对每道题。然后黄大佬根据掌握的情况,想看看是否能够选出3个学弟,使得每道题都至少有其中一个学弟能做对。
输入
一个正整数n,表示有n组案例。每组案例先是两个正整数m和p,分别表示学弟的数量和题目的数量(3<=m<=10, p<=500000)然后是m行数据,每行数据由p个字符组成,其中第i行第j个表示第i个学弟第j题做对还是做错了。字符含义如下:A——正确,W——答案不对,T——超时,M——超内存,不会有除此之外的其它字符,每个字符之间有个空格,只有A表示做对。
输出
针对每组案例,如果能够选出3个学弟,使得每道题都至少有其中一个学弟能做对,那么输出Yes,否则输出No。每组案例输出完都要换行。

这题我也还没a出来,也是可以实现但是mle,但这题还是贴一下代码,以供参考,因为案例比较小,所以我直接三重循环了。

#include<iostream>
using namespace std;
int main()
{
	int n;
	cin>>n;
	while(n--)
	{
	int m, p;
	cin>>m>>p;
	int x[m][p];
	for(int i=0;i<m;i++)
	{
		for(int j=0;j<p;j++)
		{
			char a;
			cin>>a;
			if(a=='A')x[i][j]=1;
			else x[i][j]=0;
		}
	}
	int sum=0; 
	for(int i=0;i<m;i++)
	{
		for(int j=0;j<m&&j!=i;j++)
		{
			for(int k=0;k<m&&k!=i&&k!=j;k++)
			{
				int b=1;
				for(int c=0;c<p;c++)
				{
					if(x[i][c]+x[j][c]+x[k][c]==0)
					{
						b=0;
					}
				}
				if(b==1)sum=1;
			}
		}
	}
	if(sum)cout<<"Yes"<<endl;
	else cout<<"No"<<endl;
	}
 } 

这时候还是runtime,因为我用的dev所以直接定义x[m][p],虽然这样肯定不规范。

#include<iostream>
using namespace std;
int main()
{
	int n;
	cin >> n;
	while (n--)
	{
		int m, p;
		m = 10; p = 500000;
		bool **x = new bool*[m];
		for (int i = 0; i < m; i++)
		{
			x[i] = new bool[p];
		}
		for (int i = 0; i<m; i++)
		{
			for (int j = 0; j<p; j++)
			{
				char a;
				a = 'A';
				if (a == 'A')x[i][j] = 1;
				else x[i][j] = 0;
			}
		}
		bool sum = 0;
		for (int i = 0; i<m; i++)
		{
			for (int j = 0; j<m&&j != i; j++)
			{
				for (int k = 0; k<m&&k != i&&k != j; k++)
				{
					bool b = 1;
					for (int c = 0; c<p; c++)
					{
						if (x[i][c] + x[j][c] + x[k][c] == 0)
						{
							b = 0;
						}
					}
					if (b == 1)sum = 1;
				}
			}
		}
		if (sum)cout << "Yes" << endl;
		else cout << "No" << endl;
		for (int i = 0; i < m; i++)
		{
			delete[] x[i];
		}
		delete x;
	}
	return 0;
}

但是当我这样new了一个二维数组然后delete掉的时候,又变成了mle,就很难受。

还有一点闲话

就是因为这次线上赛是这学期最后一次,所以可能下学期再更,也有可能寒假随缘更。希望发现我的bug的大佬(如果有空的话)可以评论或者+q309894263讨论!(第四题用vector炸了)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值