B - Wrath
题意&分析:
铃响杀人,一群犯人站成一排,每个人都有个爪子,长度为L_i
,当满足 j < i && j >= L_i - i 时 i 可以将 j 杀死。问最后有多少人活下来。
倒序遍历一遍,复杂度o( n ),对于每一个人都有一个可以杀人的区间,把这个区间里的人全部 kill 就可以了,求出最长的这个区间,去除掉之后剩下的就是答案。
代码如下:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll Mod = 1e9 + 7;
ll a[1000010];
ll vis[1000010];
ll n;
int main(){
std::ios::sync_with_stdio(false);
std::cin.tie(0);
while(scanf("%lld",&n) != EOF){
for(int i=1;i<=n;i++){
scanf("%lld",&a[i]);
}
ll kill = -1;
memset(vis,0,sizeof(vis));
for(int i=n;i>=1;i--){
kill --;
ll temp = a[i];
if(kill >= 0)vis[i] = 1;
kill = max(temp,kill);
}
ll ans = 0;
for(int i=1;i<=n;i++){
if(vis[i] == 0)ans ++;
}
printf("%lld\n",ans);
}
return 0;
}
C - Pride
题意&分析:
一个数列,相邻两个数 x,y 可以求 GCD(x,y),并且可以替换x,y中的一个;问最后该数列是否可以全部变成 1 。
如果可以,则:
若所有的数的GCD不是 1 ,那么输出 - 1;
若所有的数的GCD是 1,则需要知道:原数列1的个数,如果有,直接输出 n - n0(1的个数);如果没有,则算出 通过gcd求出 1 的最少步骤;对于只有一个数字的情况,只有这个数字是1才满足,否则输出-1。
代码如下:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll Mod = 1e9 + 7;
const ll MAXN = 2010;
ll a[MAXN];
ll n;
ll gcd(ll a,ll b){
return b==0? a:gcd(b,a%b);
}
int main(){
std::ios::sync_with_stdio(false);
std::cin.tie(0);
while(scanf("%lld",&n) != EOF){
ll cnt_one = 0;
for(int i=1;i<=n;i++){
scanf("%lld",&a[i]);
if(a[i] == 1)cnt_one ++;//需要计算原来的数组中的 1 ,这些事不需要在取gcd的,容易错。
}
if(cnt_one){
printf("%lld\n",n - cnt_one);continue;
}
ll tmp_gcd = a[1];
for(int i=2;i<=n;i++){
tmp_gcd = gcd(tmp_gcd,a[i]);
}
if(tmp_gcd != 1){//所有数的最大公约数不是 1 ,无解 e.g. 2 4 6 8
printf("-1\n");continue;
}
ll step = 0,ans = INF;//step记录获得1而求gcd的次数 即两个数互质
for(int i=1;i<=n;i++){
tmp_gcd = a[i];
for(int j=i+1;j<=n;j++){
tmp_gcd = gcd(tmp_gcd,a[j]);
if(tmp_gcd == 1){
step = j - i;break;
}
}
ans = min(ans,step + n - 1 - cnt_one);
}
printf("%lld\n",ans);
}
return 0;
}
D - Gluttony
题意&分析:
给定数列{an},元素互不相同,将{an}的元素重排列之后得到数列{bn},满足两数列前k项和S(ak) != S(bk);
对于一个有序的数列 a1,a2,…,an,可以构造出数列a2,a3,…,an,a1, 这样子显然可以得出前 k 项和是不会相等的。所以对于任意的一个数列{an},只需要将低 j 大的数用第 j-1 大的数替换,然后最小的那个数用最大的数替换即可。
代码如下:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll Mod = 1e9 + 7;
const ll MAXN = 30;
int a[MAXN],b[MAXN];
int n;
int main(){
std::ios::sync_with_stdio(false);
std::cin.tie(0);
while(scanf("%d",&n) != EOF){
for(int i=0;i<n;i++){
scanf("%d",&a[i]);
b[i] = a[i];
}
sort(b,b+n);
b[n] = b[0];
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
if(a[i] == b[j]){
printf("%d",b[j+1]);break;
}
}
printf("%c",(i==n-1)? '\n':' ');
}
}
return 0;
}