Codeforces Round #636 (Div. 3)
A. Candies
題目大意
給定一個n,使得x + 2x + 4x + … + 2^k-1 x = n 成立,求x,且滿足k > 1。
Solution
求一個係數1 + 2 + 4 + 2^k-1 能被n整除,n/係數 即爲答案。
代碼
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int SZ = 1e5 + 7;
const int INF = 0x3f3f3f3f;
ll n;
int main()
{
int T;
scanf("%d",&T);
while(T --)
{
scanf("%lld",&n);
ll sum = 3,t = 2;
while(n % sum != 0)
{
t *= 2;
sum += t;
}
printf("%lld\n",n/sum);
}
return 0;
}
B. Balanced Array
題目大意
給定一個n,構造一個長度爲n的數列,n保證是一個偶數,使得前n/2個元素全爲偶數,後n/2個元素全爲奇數,並且每個數字都不一樣,且前半段和後半段的和相同。
Solution
前半段的和必然是偶數,後半段如果爲奇數個,和是奇數,不合法,所以n/2必須是偶數。
如果合法,前半段按2,4,6,… 後半段按1, 3 , 5… 這樣排列,最後一個數字加上 n/2 - 1 即可。
代碼
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int SZ = 1e5 + 7;
const int INF = 0x3f3f3f3f;
int n;
int T;
int main()
{
int i;
cin>>T;
while(T--)
{
scanf("%d",&n);
if ((n / 2) % 2 == 1){printf("NO");}
else
{
printf("YES\n");
for(i=1;i<=n/2;i++)
printf("%d ",2*i);
for(i=1;i<n/2;i++)
printf("%d ",2*i-1);
printf("%d",2*i+(n/2-1));
}
printf("\n");
}
}
C. Alternating Subsequence
題目大意
給定一段序列,要求選出一個最長序列,使得序列中必須滿足異號相鄰,同號不得相鄰,如果有多個最長,選出和最大的,輸出和。
Solution
出現異號的就選擇,同號的就找較大的一個,然後繼續找異號的,再把最後一個加上即可。
代碼
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int SZ = 2e5 + 7;
const int INF = 0x3f3f3f3f;
int n,f,num[SZ];
ll s,sum;
int main()
{
int T;
scanf("%d",&T);
while(T --)
{
f = 0,sum = 0;
scanf("%d",&n);
for(int i = 1;i <= n;i ++)
{
scanf("%d",&num[i]);
if (f == 0)
{
if (num[i] < 0) f = -1;
else f = 1;
s = num[i];
}
if (f == 1 && num[i] < 0)
{
sum += s;
s = num[i];
f = -1;
}
if (f == -1 && num[i] > 0)
{
sum += s;
s = num[i];
f = 1;
}
if (num[i] > s)s = num[i];
}
sum += s;
printf("%lld\n",sum);
}
return 0;
}
D. Constant Palindrome Sum
題目描述
給定一個長度爲n的序列,其中任意一個數字的範圍爲1 <= ai <= k,現在你可以更改其中任何的數字,使得仍滿足1 <= ai <= k,且 a[i] + a[n - i + 1] = x,對於n/2對組合x必須相同,問最少修改次數。
Solution
對於每一組,只有3種選擇,不改,改一個,改兩個。
對於一組數,修改一次可達到的範圍 : min(num[i],num[n - i + 1]) + 1 到 max(num[i],num[n - i + 1]) + k。且中間要挖去不需要修改的點。變到其他值則需要修改2次,總範圍從2到2 * k。那麼做差分,再求一次前綴和,即爲改到當前x所需要修改的次數,選擇一個最小的即爲答案。
代碼
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int SZ = 2e5 + 10;
const int INF = 0x3f3f3f3f;
ll k,id,n,num[SZ];
ll vis[SZ << 1];
int main()
{
int T;
scanf("%d",&T);
while(T -- )
{
memset(vis,0,sizeof(vis));
scanf("%lld%lld",&n,&k);
for(int i = 1;i <= n;i ++)
scanf("%lld",&num[i]);
for(int i = 1;i <= n/2;i ++ )
{
vis[1] += 2;
vis[min(num[i],num[n - i + 1]) + 1] -= 2;
vis[min(num[i],num[n - i + 1]) + 1] += 1;
vis[num[i] + num[n - i + 1] + 1] += 1;
vis[num[i] + num[n - i + 1]] -= 1;
vis[max(num[i],num[n - i + 1]) + k + 1] -= 1;
vis[max(num[i],num[n - i + 1]) + k + 1] += 2;
vis[2 * k + 1] -= 2;
}
id = 1;
for(int i = 2;i <= k * 2;i ++ )
{
vis[i] += vis[i - 1];
if(vis[i] < vis[id])
id = i;
}
printf("%lld\n",vis[id]);
}
return 0;
}
2020.4.23