NEFU 大一寒假训练十四(string)2020.02.20

Summary

今天的题 emm…怎么说呢?
简单的十分简单,不简单的十分不简单。嗯~ o( ̄▽ ̄)o就这样吧。

Information

No.TitleAC/Submit
A字符串合并-string59/61
B回文字符串-string58/70
C气球-string-map59/82
D取子字符串-string55/72
Estrange string43/126
F字符串处理-string28/40
G字符串乘方-string19/33
H字符串匹配-string12/105

Problem A: 字符串合并-string (31) [59/61]

Tips

这个就不说啥了,一共也没几行,分开输出都行。

Code

#include <bits/stdc++.h>
using namespace std;

int main()
{
	string s1,s2;
	while(cin>>s1>>s2)cout<<s1+s2<<endl;
    return 0;
}

Problem B: 回文字符串-string (194) [58/70]

Tips

可以利用 reverse() 将字符串反向,再与原字符串比较。

Code

#include <bits/stdc++.h>
using namespace std;

int main()
{
	string s1,s2;
	int n;
	cin>>n;
	while(n--)
	{
		cin>>s1;
		s2=s1;
		reverse(s1.begin(),s1.end());
		if(s1==s2)cout<<"YES"<<endl;
		else cout<<"NO"<<endl;
	}
    return 0;
}

Problem C: 气球-string-map (549) [59/82]

Tips

可以用 map 存储气球数量,读入时分别更新最多的气球数量及颜色。

Code

#include <bits/stdc++.h>
using namespace std;

int main()
{
	string s,maxb;
	int n,maxn;
	map<string,int>m;
	while(cin>>n&&n!=0)
	{
		maxn=0;
		m.clear();
		while(n--)
		{
			cin>>s;
			m[s]++;
			if(m[s]>maxn)
			{
				maxn=m[s];
				maxb=s;
			}
		}
		cout<<maxb<<endl;
	}
    return 0;
}

Problem D: 取子字符串-string (1001) [55/72]

Tips

使用 substr(begin,num) 得到从 begin 开始长度为 num 的子串。

Code

#include <bits/stdc++.h>
using namespace std;

int main()
{
	string s;
	int n,m;
	while(cin>>s>>n>>m)cout<<s.substr(n-1,m-n+1)<<endl;
    return 0;
}

Problem E: strange-string (1019) [43/126]

Tips

范围很小,十分暴力。

Code

#include <bits/stdc++.h>
using namespace std;

int main()
{
	string s;
	int n,m,ok;
	while(cin>>s)
	{
		switch(s.length())
		{
			case 3:
				if(s[0]!=s[1]&&s[0]!=s[2]&&s[2]!=s[1])cout<<"YES"<<endl;
				else cout<<"NO"<<endl;
				break;
			case 6:
				if(s[0]==s[1]&&s[2]==s[3]&&s[4]==s[5]&&s[0]!=s[2]&&s[0]!=s[4]&&s[2]!=s[4])cout<<"YES"<<endl;
				else cout<<"NO"<<endl;
				break;
			case 9:
				ok=1;
				for(int i=0;i<9;i+=3)
				{
					if(s[i]!=s[i+1]||s[i]!=s[i+2])
					{
						ok=0;
						break;
					}
				}
				if(ok&&s[0]!=s[3]&&s[0]!=s[6]&&s[3]!=s[6])cout<<"YES"<<endl;
				else cout<<"NO"<<endl;
				break;
			default:
				cout<<"NO"<<endl;
		}
	}
    return 0;
}

Problem F: 字符串处理-string (2132) [28/40]

Tips

难度从这题开始上升,raising ~
思路就是从头扫到尾,分别处理奇数情况和偶数情况。
奇数处理: 以当前扫到的第 i 个为中心向两侧延申,如果左右两侧相等,答案+1,如果不相等则结束。
偶数处理: 假设当前扫到的第 i 个,如果它和它的下一个(即第 i+1 个)相等,则向两侧延申,处理方法和奇数相同,如果左右两侧相等,答案+1,如果不相等则结束。
最后输出答案即可。

Code

#include <bits/stdc++.h>
using namespace std;

int main()
{
	string s;
	int n,m,ok,l,r;
	long long ans;
	while(cin>>s)
	{
		ans=0;
		for(int i=0;i<s.length();i++)
		{
			ans++;
			l=r=i;
			while(l-1>=0&&r+1<s.length()) //奇数处理
			{
				l--;r++;
				if(s[l]!=s[r])break;
				ans++;
			}
			if(i+1<s.length()) //偶数处理
			{
				l=i;r=i+1;
				if(s[l]==s[r])ans++;
				else continue;
				while(l-1>=0&&r+1<s.length())
				{
					l--;r++;
					if(s[l]!=s[r])break;
					ans++;
				}
			}
		}
		cout<<ans<<endl;
	}
    return 0;
}

Problem G: 字符串乘方-string (2131) [19/33]

Tips

这道题可以尝试切分字符串,把字符串切成相等的 i 段。
因此 i 一定是字符串总长度的一个因子,枚举字符串的因子判断能否正好切成 i 段即可。

Code

#include<bits/stdc++.h>
using namespace std;
int main()
{
	ios::sync_with_stdio(0);
	string s;
	int i,j,ok,len;
	while(cin>>s)
	{
		len=s.length();
		if(s[0]=='.'&&len==1)return 0;
		for(i=1;i<=len/2;i++) //枚举因子
		{
			if(len%i==0) //是一个因子
			{
				ok=1;
				for(j=i;j<len;j++) //判断是否符合要求
				{
					if(s[j]!=s[j%i])
					{
						ok=0;
						break;
					}
				}
				if(ok)break;
			}
		}
		if(ok)cout<<len/i<<endl;
		else cout<<1<<endl;
	}
	return 0;
}

Problem H: 字符串匹配-string (2130) [12/105]

Tips

这题有点坑,数据范围也没给,样例括号还打成了全角符号。
想算法想了好长时间,结果一个大佬说他用了一个 O(mn) 的算法过了。
emm… Let me think think… 啊?啥?O(mn)?那不就是暴力吗???
于是就有了下面十分暴力的代码。

⚠ 掉坑警告 ⚠

  1. 如果比值为 1 不要输出 1/1。
  2. 括号和逗号是半角的,不要忘了等号两边的空格。
  3. 暴力扫描不要上头越界。

Code

#include <bits/stdc++.h>
using namespace std;

int main()
{
	ios::sync_with_stdio(0);
	string s1,s2;
	int cnt,ans,sum,gcd;
	while(cin>>s1)
	{
		if(s1=="-1")return 0;
		ans=0;
		cin>>s2;
		for(int i=0;i<s1.length();i++)
		{
			cnt=0;
			for(int j=0;j<s2.length();j++)
			{
				if(i+j>s1.length())break;
				if(s1[i+j]==s2[j])cnt++;
			}
			if(cnt>ans)ans=cnt;
		}
		for(int i=0;i<s2.length();i++)
		{
			cnt=0;
			for(int j=0;j<s1.length();j++)
			{
				if(i+j>s2.length())break;
				if(s2[i+j]==s1[j])cnt++;
			}
			if(cnt>ans)ans=cnt;
		}
		sum=s1.length()+s2.length();
		ans*=2;
		if(ans==sum)
		{
			cout<<"appx("<<s1<<","<<s2<<") = 1"<<endl;
			continue;
		}
		if(ans==0)
		{
			cout<<"appx("<<s1<<","<<s2<<") = 0"<<endl;
			continue;
		}
		gcd=__gcd(ans,sum);
		cout<<"appx("<<s1<<","<<s2<<") = "<<ans/gcd<<"/"<<sum/gcd<<endl;
	}
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值