1.
题目:Vicious Keyboard
地址:http://codeforces.com/problemset/problem/801/A
大体题意是求给出的一串字符中VK的最大数量,最多可以改变其中一个字符。
AC代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <cmath>
using namespace std;
int main()
{
string s;
cin>>s;
int flag=0;
int ans=0;
if(s.length()==2)//长度为2的时候只有KV这种情况为0.其余的三种情况都可以通过改变或者不改变得到数量为1
{
if(s!="KV")
{
cout<<"1"<<endl;
return 0;
}
else
{
cout<<"0"<<endl;
return 0;
}
}
else if(s.length()==1)//数量为1的情况只有0
{
cout<<"0"<<endl;
return 0;
}
else
{
int len=s.length();
for(int i=0;i<len-1;i++)
{
if(s[i]=='V'&&s[i+1]=='K')//如果找到VK,直接ans++,别忘了i++
{
ans++;
i++;
}
else if(s[i]=='V'&&s[i+1]=='V')//如果找到VV,这时候要判断第二个V后面是否是K,如果是K,那么优先找VK,否则才标记一下说明这个地方可以通过改变得到一个VK
{
if(s[i+2]=='K')
continue;
else
{
flag=1;
i++;
}
}
else if(s[i]=='K'&&s[i+1]=='K')
{
flag=1;
i++;
}
else if(s[i]=='K'&&s[i+1]=='V')//当找到KV时,直接continue,因为KV无论怎么样都不能变成VK
continue;
}
if(flag)//当找到VV,KK时,标记为1,说明可以通过改变得到一个VK
ans+=1;
cout<<ans<<endl;
return 0;
}
}
2.
Odd sum
地址:http://codeforces.com/problemset/problem/797/B
题意就是给出n个数字,求这n个数字最大的奇数和。
思路1:奇数和肯定是偶数和奇数相加,所以首先把所有的正偶数相加,将奇数序列从大到小排序,先加上第一个奇数,这时候的和肯定是一个奇数,只有再加偶数才能保证最后是奇数和,所以剩下的奇数两个为一组,如果相加大于0,那就加到和上,最后输出答案。
思路2:把所有的正数加起来,然后判断是否为奇数,如果是直接输出答案。如果不是,找到绝对值最小的那个奇数,然后用现在的和减去这个奇数的绝对值,最后就是答案。
AC1:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <cmath>
using namespace std;
const int maxn=1e5+5;
int cmp(int a,int b)
{
return a>b;
}
int main()
{
int n;
cin>>n;
int su[maxn];
int cnt=0;
long long ans=0;
for(int i=0;i<n;i++)
{
int a;
cin>>a;
if(a%2!=0)
su[cnt++]=a;
else if(a>0)
ans+=a;
}
sort(su,su+cnt,cmp);
ans+=su[0];
for(int i=1;i<cnt-1;i++)
{
if((su[i]+su[i+1])>=0)
{
ans+=su[i]+su[i+1];
i++;
}
}
cout<<ans<<endl;
}
AC2:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <cmath>
using namespace std;
const int maxn=1e5+5;
int cmp(int a,int b)
{
return a>b;
}
int main()
{
int n;
cin>>n;
int su[maxn];
int cnt=0;
long long ans=0;
int maxx=-0x7fffffff;
int minn=0x7fffffff;
for(int i=0;i<n;i++)
{
int a;
cin>>a;
if(a>0)
ans+=a;
if(a%2!=0)
{
if(a>0)
{
minn=min(minn,a);
}
else if(a<0)
{
maxx=max(maxx,a);
}
}
}
if(ans%2==1)
{
cout<<ans<<endl;
return 0;
}
else
{
int m=min(abs(maxx),abs(minn));
ans-=m;
cout<<ans<<endl;
return 0;
}
}
3.
Japanese Crosswords Strike Back
地址:https://cn.vjudge.net/problem/1161922/origin
给出一段二进制数字,有几个1相邻就是几,n代表有几组这样的1相邻,比如说0110111,n就是2,构成的数组就是{2,3}。现在给出两个数,n代表数组里面数的个数,x代表二进制数字的长度。下面n个数代表1的长度。
因为两组1之间用一个0隔开,所以用总长度把所有的1的长度减去,然后与n-1作比较,如果相等,那就YES,否则NO。
AC代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <cmath>
using namespace std;
int main()
{
int n,x;
cin>>n>>x;
int cnt=0;
for(int i=0;i<n;i++)
{
int a;
cin>>a;
cnt+=a;
}
x-=cnt;
if(n-1==x)
cout<<"YES"<<endl;
else
cout<<"NO"<<endl;
return 0;
}
4.
Bertown Subway
地址:https://cn.vjudge.net/problem/1161924/origin
通俗地讲,例如第一个案例,2.1.3 ,第一个站的终点站是2,第二个站的终点站是1,第三个站的终点站是3。这时候1.2成一个环,3自成一个环。可以改变两个站的终点站,使得(a,b)有向的数量最大。还是上面这个例子,经过改变后变成2.3.1,这时候第一个站点的终点站是2,第二个站点的终点站是3,第三个站点的终点站是1,1.2.3这三个站成了一个环,那(a,b)就从原来的三个变成了现在的九个。
思路:求出每个环的大小,把最大的的两个合并,剩下的不变,结果是每个环的平方和,注意要用long long。
AC代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <cmath>
using namespace std;
const int maxn=1e6+5;
int p[maxn];
int vis[maxn];
int cnt[maxn];
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>p[i];
}
int x,sum;
for(int i=1;i<=n;i++)
{
if(vis[i]) continue;
x=p[i];
sum=1;
vis[i]=1;
while(!vis[x])
{
sum++;
vis[x]=1;
x=p[x];
}
cnt[i]=sum;
}
sort(cnt+1,cnt+1+n);
long long int ans=0;
if(n>1)
ans=(long long)(cnt[n]+cnt[n-1])*(long long )(cnt[n]+cnt[n-1]);//合并两个最大的环
else
ans=1;
for(int i=1;i<=n-2;i++)
{
ans+=(long long)(cnt[i])*(long long)(cnt[i]);
}
cout<<ans<<endl;
return 0;
}
5.
Ancient Cipher
地址:http://poj.org/problem?id=2159
给出两串字符,问是否可以把其中一个经过相应的编码后得到另一串字符。
思路:字母可以重排,那么次序就不重要了,分别统计两串字符中各个字母的个数,然后进行排序,判断两个数组是否相等,例如数组1有一个J,两个W,数组2有一个I,两个Q,这时候就是相等,虽然字母不同,但是字母的个数相同。
AC代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <algorithm>
using namespace std;
int main()
{
int num1[100],num2[100];
string s1,s2;
cin>>s1>>s2;
memset(num1,0,sizeof(num1));
memset(num2,0,sizeof(num2));
int len=s1.length();
for(int i=0;i<len;i++)
{
num1[s1[i]-'A']++;
num2[s2[i]-'A']++;
}
sort(num1,num1+26);
sort(num2,num2+26);
int flag=0;
for(int i=0;i<26;i++)
{
if(num1[i]!=num2[i])
{
flag=1;
break;
}
}
if(!flag)
cout<<"YES"<<endl;
else
cout<<"NO"<<endl;
return 0;
}