A. Omkar and Password

题目:​​http://codeforces.com/contest/1392/problem/A​

题解:看似觉得有些难手,但是仔细思考下就会发现,只要整个数组中有1个与其它不一样,那么最终都会合成为1个数字,只有全部一样的数字才不能合成。

代码:

#include<bits/stdc++.h>    //POJ不支持
#define rep(i,a,n) for (int i=a;i<=n;i++)//i为循环变量,a为初始值,n为界限值,递增
#define per(i,a,n) for (int i=a;i>=n;i--)//i为循环变量, a为初始值,n为界限值,递减。
#define pb push_back
#define IOS ios::sync_with_stdio(false);cin.tie(0); cout.tie(0)
#define fi first
#define se second
#define mp make_pair

using namespace std;

const int inf = 0x3f3f3f3f;//无穷大
const int maxn = 200010;//最大值。
typedef long long ll;
typedef long double ld;
typedef pair<ll, ll> pll;
typedef pair<int, int> pii;

int main()
{
IOS;
ll t,n;
cin>>t;
while(t--)
{
cin>>n;
ll i,x;
bool flag=false;
ll sum=0;
for(i=1;i<=n;i++)
{
cin>>x;
if(i==1)
sum=x;
if(i!=1&&x!=sum)
flag=true;
}
if(flag==true)
cout<<"1"<<endl;
else
cout<<n<<endl;
}
return 0;
}

B. Omkar and Infinity Clock

题目:​​http://codeforces.com/contest/1392/problem/B​

题解:这是一道很简单的数组的值变化问题,最终只会有两组数组出现,只要根据K的奇偶性,来判断应该输出哪组数组即可

代码:

#include<bits/stdc++.h>    //POJ不支持
#define rep(i,a,n) for (int i=a;i<=n;i++)//i为循环变量,a为初始值,n为界限值,递增
#define per(i,a,n) for (int i=a;i>=n;i--)//i为循环变量, a为初始值,n为界限值,递减。
#define pb push_back
#define IOS ios::sync_with_stdio(false);cin.tie(0); cout.tie(0)
#define fi first
#define se second
#define mp make_pair

using namespace std;

const int inf = 0x3f3f3f3f;//无穷大
const int maxn = 200010;//最大值。
typedef long long ll;
typedef long double ld;
typedef pair<ll, ll> pll;
typedef pair<int, int> pii;

ll a[maxn],b[maxn];
int main()
{
ll t,n,k;
ll i,j;
cin>>t;
while(t--)
{
cin>>n>>k;
ll m=-1000000000;
for(i=1;i<=n;i++)
{
cin>>a[i];
m=max(m,a[i]);
}
ll f=-1000000000;
for(i=1;i<=n;i++)
{
a[i]=m-a[i];
f=max(f,a[i]);
}
for(i=1;i<=n;i++)
{
b[i]=f-a[i];
}
if(k%2==1)
{
for(i=1;i<=n;i++)
{
if(i!=1)
cout<<" "<<a[i];
else
cout<<a[i];
}
}
else
{
for(i=1;i<=n;i++)
{
if(i!=1)
cout<<" "<<b[i];
else
cout<<b[i];
}
}
cout<<endl;
}
return 0;
}

C. Omkar and Waterslide

题目:​​http://codeforces.com/contest/1392/problem/C​

题解:一开始设想的是从前往后找,发现要考虑的东西太多了,之后看了看别人的代码后,发现从后往前找就非常的简单了,只要当前的数比前一个小,就一直加到前一个数一样大;如果比他小,就继续比较那个数与他前面的数进行比较。最终得到的一定是一个单调不递减数组,并且操作次数也是最少的

代码:

#include<bits/stdc++.h>    //POJ不支持
#define rep(i,a,n) for (int i=a;i<=n;i++)//i为循环变量,a为初始值,n为界限值,递增
#define per(i,a,n) for (int i=a;i>=n;i--)//i为循环变量, a为初始值,n为界限值,递减。
#define pb push_back
#define IOS ios::sync_with_stdio(false);cin.tie(0); cout.tie(0)
#define fi first
#define se second
#define mp make_pair

using namespace std;

const int inf = 0x3f3f3f3f;//无穷大
const int maxn = 200010;//最大值。
typedef long long ll;
typedef long double ld;
typedef pair<ll, ll> pll;
typedef pair<int, int> pii;
ll a[maxn];
int main()
{
IOS;
ll i,j,t,n;
cin>>t;
while(t--)
{
cin>>n;
ll ans=0;
for(i=1;i<=n;i++)
cin>>a[i];
for(i=n;i>=2;i--)
{
if(a[i]<a[i-1])
ans+=a[i-1]-a[i];
}
cout<<ans<<endl;
}
return 0;
}

D. Omkar and Bed Wars

题目:​​http://codeforces.com/contest/1392/problem/D​

题解:

首先我们现将环破成链,然后对他进行分析。

共有两种情况:其一为全部是L或全部是R,对于这种情况分三种讨论,当n小于等于2时,输出0;当n==3时,输出1;当n大于3时,输出n/3+(n%3>0)即可

其二就是有L也有R,根据第一步我们找到对应的flag为断点,将环变成链,然后我们首先找到连续相同字母出现的次数进行统计,他们的最少变化次数是cnt/3,因此我们只需要找出在最终形成的链中,相同字母出现的次数/3,累加即可。

这里切记注意,flag要用tmp替换一下,因为在for循环里i<n+flag,其中的flag如果不进行替换,那么下面的flag移动,上面循环里的也会变化,因此注意!!

代码:

 

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=4e5+10;
ll n;
char s[maxn];

int main()
{
int t,i;
cin>>t;
while(t--)
{
ll ans=0;
cin>>n;
scanf("%s",s);
for(i=0;i<n;i++)
s[i+n]=s[i];
int flag=-1;
for(i=0;i<n;i++)
{
if(s[0]!=s[i])
{
flag=i;
break;
}
}
if(flag==-1)
{
if(n<=2)
cout<<"0"<<endl;
else if(n==3)
cout<<"1"<<endl;
else
{
cout<<n/3+(n%3>0)<<endl;
}
}
else
{
ll cnt=0;
ll tmp=flag;
for(i=flag;i<n+flag;i++)
{
if(s[i]==s[tmp])
cnt++;
else
{
ans+=cnt/3;
tmp=i;
cnt=1;
}
}
ans+=cnt/3;
cout<<ans<<endl;
}
}
return 0;
}