本题解参加2021周行新春码拉松
比赛链接
Problem.A 等差数列
题解
我们需要知道等差数列前n项和的第二个公式,不知道的话直接手推也行。
公式:
S
n
=
n
∗
a
1
+
n
∗
(
n
−
1
)
∗
d
2
S_{n}=n*a_{1}+\frac{n*(n-1)*d}{2}
Sn=n∗a1+2n∗(n−1)∗d
公式里面的
d
=
a
2
−
a
1
d=a_{2}-a_{1}
d=a2−a1,然后直接带入公式即可。
trick:数据范围会爆int,注意开long long。
代码
#include <bits/stdc++.h>
#define PI atan(1.0)*4
#define rp(i,s,t) for (register int i = (s); i <= (t); i++)
#define RP(i,t,s) for (register int i = (t); i >= (s); i--)
#define sc(x) scanf("%d",&x)
#define scl(x) scanf("%lld",&x)
#define ll long long
#define ull unsigned long long
#define mst(a,b) memset(a,b,sizeof(a))
#define lson rt<<1,l,m
#define rson rt<<1|1,m+1,r
#define pii pair<int,int>
#define pll pair<ll,ll>
#define pil pair<int,ll>
#define m_p make_pair
#define p_b push_back
#define ins insert
#define era erase
#define INF 0x3f3f3f3f
#define inf 0x3f3f3f3f3f3f3f3f
#define dg if(debug)
#define pY puts("YES")
#define pN puts("NO")
#define outval(a) cout << "Debuging...|" << #a << ": " << a << "\n";
#define outval2(a,b) cout << "Debuging...|" << #a << ": " << a <<"\t"<< #b << ": " << b << "\n";
#define outval3(a,b,c) cout << "Debuging...|" << #a << ": " << a <<"\t"<< #b << ": " << b <<"\t"<< #c << ": " << c << "\n";
using namespace std;
int debug = 0;
ll gcd(ll a,ll b){
return b?gcd(b,a%b):a;
}
ll lcm(ll a,ll b){
return a/gcd(a,b)*b;
}
inline int read(){
int s=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-') f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
s=s*10+ch-'0';
ch=getchar();
}
return s*f;
}
const int N = 1e5+7;
int a[N];
void solve(){
ll a1,a2,n;scl(a1);scl(a2);scl(n);
cout<<n*a1+n*(n-1)/2*(a2-a1)<<endl;
}
int main(){
//ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#ifdef ONLINE_JUDGE
#else
freopen("in.txt", "r", stdin);
//debug = 1;
#endif
//time_t beg, end;
//if(debug) beg = clock();
int T=1;
while(T--) solve();
/*
if(debug) {
end = clock();
printf("time:%.2fs\n", 1.0 * (end - beg) / CLOCKS_PER_SEC);
}
*/
return 0;
}
Problem.B 士兵选择
题解
数据范围给的比较小,我们直接枚举两个士兵就行了。
比较好的做法是先对士兵进行排序(按照身高从低低到高)
然后先
O
(
n
)
O(n)
O(n)枚举当前士兵
a
[
i
]
a[i]
a[i],二分出大于当前士兵身高
+
d
+d
+d的第一个士兵的下标
i
d
id
id,不难发现
[
i
+
1
,
i
d
]
[i+1,id]
[i+1,id]范围的士兵都满足条件,最后不要忘记乘2就行了。
这里给出二分的代码
代码
#include <bits/stdc++.h>
#define PI atan(1.0)*4
#define rp(i,s,t) for (register int i = (s); i <= (t); i++)
#define RP(i,t,s) for (register int i = (t); i >= (s); i--)
#define sc(x) scanf("%d",&x)
#define scl(x) scanf("%lld",&x)
#define ll long long
#define ull unsigned long long
#define mst(a,b) memset(a,b,sizeof(a))
#define lson rt<<1,l,m
#define rson rt<<1|1,m+1,r
#define pii pair<int,int>
#define pll pair<ll,ll>
#define pil pair<int,ll>
#define m_p make_pair
#define p_b push_back
#define ins insert
#define era erase
#define INF 0x3f3f3f3f
#define inf 0x3f3f3f3f3f3f3f3f
#define dg if(debug)
#define pY puts("YES")
#define pN puts("NO")
#define outval(a) cout << "Debuging...|" << #a << ": " << a << "\n";
#define outval2(a,b) cout << "Debuging...|" << #a << ": " << a <<"\t"<< #b << ": " << b << "\n";
#define outval3(a,b,c) cout << "Debuging...|" << #a << ": " << a <<"\t"<< #b << ": " << b <<"\t"<< #c << ": " << c << "\n";
using namespace std;
int debug = 0;
ll gcd(ll a,ll b){
return b?gcd(b,a%b):a;
}
ll lcm(ll a,ll b){
return a/gcd(a,b)*b;
}
inline int read(){
int s=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-') f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
s=s*10+ch-'0';
ch=getchar();
}
return s*f;
}
const int N = 1e5+7;
int a[N];
void solve(){
int n=read(),d=read();
rp(i,1,n) a[i]=read();
sort(a+1,a+1+n);
int ans=0;
rp(i,1,n){
int id=upper_bound(a+1,a+1+n,a[i]+d)-a;
id--;
id=min(id,n);
ans+=id-i;
}
cout<<ans*2<<endl;
}
int main(){
//ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#ifdef ONLINE_JUDGE
#else
freopen("in.txt", "r", stdin);
//debug = 1;
#endif
//time_t beg, end;
//if(debug) beg = clock();
int T=1;
while(T--) solve();
/*
if(debug) {
end = clock();
printf("time:%.2fs\n", 1.0 * (end - beg) / CLOCKS_PER_SEC);
}
*/
return 0;
}
Problem.C 递增序列
题解
从前往后贪心的加就行了,每当遇到下一个数比当前数小,就对下一个数进行加 d d d的操作,知道下一个数比当前数大
代码
#include <bits/stdc++.h>
#define PI atan(1.0)*4
#define rp(i,s,t) for (register int i = (s); i <= (t); i++)
#define RP(i,t,s) for (register int i = (t); i >= (s); i--)
#define sc(x) scanf("%d",&x)
#define scl(x) scanf("%lld",&x)
#define ll long long
#define ull unsigned long long
#define mst(a,b) memset(a,b,sizeof(a))
#define lson rt<<1,l,m
#define rson rt<<1|1,m+1,r
#define pii pair<int,int>
#define pll pair<ll,ll>
#define pil pair<int,ll>
#define m_p make_pair
#define p_b push_back
#define ins insert
#define era erase
#define INF 0x3f3f3f3f
#define inf 0x3f3f3f3f3f3f3f3f
#define dg if(debug)
#define pY puts("YES")
#define pN puts("NO")
#define outval(a) cout << "Debuging...|" << #a << ": " << a << "\n";
#define outval2(a,b) cout << "Debuging...|" << #a << ": " << a <<"\t"<< #b << ": " << b << "\n";
#define outval3(a,b,c) cout << "Debuging...|" << #a << ": " << a <<"\t"<< #b << ": " << b <<"\t"<< #c << ": " << c << "\n";
using namespace std;
int debug = 0;
ll gcd(ll a,ll b){
return b?gcd(b,a%b):a;
}
ll lcm(ll a,ll b){
return a/gcd(a,b)*b;
}
inline int read(){
int s=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-') f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
s=s*10+ch-'0';
ch=getchar();
}
return s*f;
}
const int N = 1e5+7;
ll a[N],d;
void solve(){
int n=read();
scl(d);
rp(i,1,n) scl(a[i]);
ll ans=0;
rp(i,2,n){
if(a[i]<=a[i-1]){
ll num=(a[i-1]-a[i])/d+1;
a[i]+=num*d;
ans+=num;
// outval2(i,num);
}
}
cout<<ans<<endl;
}
int main(){
//ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#ifdef ONLINE_JUDGE
#else
freopen("in.txt", "r", stdin);
//debug = 1;
#endif
//time_t beg, end;
//if(debug) beg = clock();
int T=1;
while(T--) solve();
/*
if(debug) {
end = clock();
printf("time:%.2fs\n", 1.0 * (end - beg) / CLOCKS_PER_SEC);
}
*/
return 0;
}
Problem.D Easy Problem
题解
当字符串中字符的最大出现次数为 1 1 1且字符串长度不等于 1 1 1时,输出 N O NO NO,否则输出 Y E S YES YES。
代码
#include <bits/stdc++.h>
#define PI atan(1.0)*4
#define rp(i,s,t) for (register int i = (s); i <= (t); i++)
#define RP(i,t,s) for (register int i = (t); i >= (s); i--)
#define sc(x) scanf("%d",&x)
#define scl(x) scanf("%lld",&x)
#define ll long long
#define ull unsigned long long
#define mst(a,b) memset(a,b,sizeof(a))
#define lson rt<<1,l,m
#define rson rt<<1|1,m+1,r
#define pii pair<int,int>
#define pll pair<ll,ll>
#define pil pair<int,ll>
#define m_p make_pair
#define p_b push_back
#define ins insert
#define era erase
#define INF 0x3f3f3f3f
#define inf 0x3f3f3f3f3f3f3f3f
#define dg if(debug)
#define pY puts("YES")
#define pN puts("NO")
#define outval(a) cout << "Debuging...|" << #a << ": " << a << "\n";
#define outval2(a,b) cout << "Debuging...|" << #a << ": " << a <<"\t"<< #b << ": " << b << "\n";
#define outval3(a,b,c) cout << "Debuging...|" << #a << ": " << a <<"\t"<< #b << ": " << b <<"\t"<< #c << ": " << c << "\n";
using namespace std;
int debug = 0;
ll gcd(ll a,ll b){
return b?gcd(b,a%b):a;
}
ll lcm(ll a,ll b){
return a/gcd(a,b)*b;
}
inline int read(){
int s=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-') f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
s=s*10+ch-'0';
ch=getchar();
}
return s*f;
}
const int N = 1e5+7;
int cnt[26];
/*
aaabbbcccd
*/
void solve(){
string s;cin>>s;
int len=s.size();
rp(i,0,len-1) cnt[s[i]-'a']++;
int Max=0;
rp(i,0,25) Max=max(cnt[i],Max);
if(Max==1&&len!=1) pN;
else pY;
}
int main(){
//ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#ifdef ONLINE_JUDGE
#else
freopen("in.txt", "r", stdin);
//debug = 1;
#endif
//time_t beg, end;
//if(debug) beg = clock();
int T=1;
while(T--) solve();
/*
if(debug) {
end = clock();
printf("time:%.2fs\n", 1.0 * (end - beg) / CLOCKS_PER_SEC);
}
*/
return 0;
}
Problem.E 数列
题解
加上当前位置开始填
1
1
1,那么从前位置开始连续
1
1
1的长度就是从当前位置开始到遇到的第一个填
0
0
0的位置
−
1
-1
−1,
0
0
0的情况类似。
那么直接按照模拟枚举就行了。
注意最后一部分到n截止的情况。
代码
#include <bits/stdc++.h>
#define PI atan(1.0)*4
#define rp(i,s,t) for (register int i = (s); i <= (t); i++)
#define RP(i,t,s) for (register int i = (t); i >= (s); i--)
#define sc(x) scanf("%d",&x)
#define scl(x) scanf("%lld",&x)
#define ll long long
#define ull unsigned long long
#define mst(a,b) memset(a,b,sizeof(a))
#define lson rt<<1,l,m
#define rson rt<<1|1,m+1,r
#define pii pair<int,int>
#define pll pair<ll,ll>
#define pil pair<int,ll>
#define m_p make_pair
#define p_b push_back
#define ins insert
#define era erase
#define INF 0x3f3f3f3f
#define inf 0x3f3f3f3f3f3f3f3f
#define dg if(debug)
#define pY puts("YES")
#define pN puts("NO")
#define outval(a) cout << "Debuging...|" << #a << ": " << a << "\n";
#define outval2(a,b) cout << "Debuging...|" << #a << ": " << a <<"\t"<< #b << ": " << b << "\n";
#define outval3(a,b,c) cout << "Debuging...|" << #a << ": " << a <<"\t"<< #b << ": " << b <<"\t"<< #c << ": " << c << "\n";
using namespace std;
int debug = 0;
ll gcd(ll a,ll b){
return b?gcd(b,a%b):a;
}
ll lcm(ll a,ll b){
return a/gcd(a,b)*b;
}
inline int read(){
int s=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-') f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
s=s*10+ch-'0';
ch=getchar();
}
return s*f;
}
const int N = 1e6+7;
struct node{
int pos,op;
}p[N];
void solve(){
int m=read(),n=read();
int ans1=0,ans2=0;
rp(i,1,m) p[i].pos=read(),p[i].op=read();
rp(i,1,m){
int cur_op=p[i].op;
int cur_pos=p[i].pos;
while(i+1<=m&&p[i+1].op==cur_op) i++;
if(i==m){
if(cur_op==1) ans1=max(ans1,n-cur_pos+1);
else ans2=max(ans2,n-cur_pos+1);
}
else{
if(cur_op==1) ans1=max(ans1,p[i+1].pos-cur_pos);
else ans2=max(ans2,p[i+1].pos-cur_pos);
}
}
cout<<ans1<<" "<<ans2<<endl;
}
int main(){
//ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#ifdef ONLINE_JUDGE
#else
freopen("in.txt", "r", stdin);
//debug = 1;
#endif
//time_t beg, end;
//if(debug) beg = clock();
int T=1;
while(T--) solve();
/*
if(debug) {
end = clock();
printf("time:%.2fs\n", 1.0 * (end - beg) / CLOCKS_PER_SEC);
}
*/
return 0;
}
Problem.F DNA
题解
用
m
a
p
map
map维护每个
D
N
A
DNA
DNA序列的个数,然后枚举每个
D
N
A
DNA
DNA序列,判断是否存在与它匹配的序列,有的话答案加一,并且在
m
a
p
map
map中减去它们自身所占的数量。
trick:枚举时不仅要判断是否存在与之匹配的
D
N
A
DNA
DNA序列,还要判断当前枚举的
D
N
A
DNA
DNA序列是否已经被之前匹配删除过。
代码
#include <bits/stdc++.h>
#define PI atan(1.0)*4
#define rp(i,s,t) for (register int i = (s); i <= (t); i++)
#define RP(i,t,s) for (register int i = (t); i >= (s); i--)
#define sc(x) scanf("%d",&x)
#define scl(x) scanf("%lld",&x)
#define ll long long
#define ull unsigned long long
#define mst(a,b) memset(a,b,sizeof(a))
#define lson rt<<1,l,m
#define rson rt<<1|1,m+1,r
#define pii pair<int,int>
#define pll pair<ll,ll>
#define pil pair<int,ll>
#define m_p make_pair
#define p_b push_back
#define ins insert
#define era erase
#define INF 0x3f3f3f3f
#define inf 0x3f3f3f3f3f3f3f3f
#define dg if(debug)
#define pY puts("YES")
#define pN puts("NO")
#define outval(a) cout << "Debuging...|" << #a << ": " << a << "\n";
#define outval2(a,b) cout << "Debuging...|" << #a << ": " << a <<"\t"<< #b << ": " << b << "\n";
#define outval3(a,b,c) cout << "Debuging...|" << #a << ": " << a <<"\t"<< #b << ": " << b <<"\t"<< #c << ": " << c << "\n";
using namespace std;
int debug = 0;
ll gcd(ll a,ll b){
return b?gcd(b,a%b):a;
}
ll lcm(ll a,ll b){
return a/gcd(a,b)*b;
}
inline int read(){
int s=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-') f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
s=s*10+ch-'0';
ch=getchar();
}
return s*f;
}
const int N = 1e5+7;
map<string,int> mp;
string s[N];
void solve(){
int n=read();
rp(i,1,n){
cin>>s[i];
mp[s[i]]++;
}
int ans=0;
rp(i,1,n){
int len=s[i].size();
string ss="";
rp(j,0,len-1){
if(s[i][j]=='A') ss+="T";
if(s[i][j]=='T') ss+="A";
if(s[i][j]=='G') ss+="C";
if(s[i][j]=='C') ss+="G";
}
if(ss==s[i]){
if(mp.find(ss)!=mp.end()&&mp[ss]>=2){
mp[ss]-=2;
ans++;
}
}
else if(mp.find(ss)!=mp.end()&&mp[ss]>=1&&mp[s[i]]>=1){
mp[ss]--;
mp[s[i]]--;
ans++;
}
}
cout<<ans<<endl;
}
int main(){
//ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#ifdef ONLINE_JUDGE
#else
freopen("in.txt", "r", stdin);
//debug = 1;
#endif
//time_t beg, end;
//if(debug) beg = clock();
int T=1;
while(T--) solve();
/*
if(debug) {
end = clock();
printf("time:%.2fs\n", 1.0 * (end - beg) / CLOCKS_PER_SEC);
}
*/
return 0;
}
Problem.G 三棱锥
题解
手推几个数据,然后oeis一发,第一个符合的就是公式,然后按照公式输出即可。
正解应该是dp,算是比较常见的dp,前面题解也给出了dp的解法。
注意取模要考虑逆元
代码
#include <bits/stdc++.h>
#define PI atan(1.0)*4
#define rp(i,s,t) for (register int i = (s); i <= (t); i++)
#define RP(i,t,s) for (register int i = (t); i >= (s); i--)
#define sc(x) scanf("%d",&x)
#define scl(x) scanf("%lld",&x)
#define ll long long
#define ull unsigned long long
#define mst(a,b) memset(a,b,sizeof(a))
#define lson rt<<1,l,m
#define rson rt<<1|1,m+1,r
#define pii pair<int,int>
#define pll pair<ll,ll>
#define pil pair<int,ll>
#define m_p make_pair
#define p_b push_back
#define ins insert
#define era erase
#define INF 0x3f3f3f3f
#define inf 0x3f3f3f3f3f3f3f3f
#define dg if(debug)
#define pY puts("YES")
#define pN puts("NO")
#define outval(a) cout << "Debuging...|" << #a << ": " << a << "\n";
#define outval2(a,b) cout << "Debuging...|" << #a << ": " << a <<"\t"<< #b << ": " << b << "\n";
#define outval3(a,b,c) cout << "Debuging...|" << #a << ": " << a <<"\t"<< #b << ": " << b <<"\t"<< #c << ": " << c << "\n";
using namespace std;
int debug = 0;
ll gcd(ll a,ll b){
return b?gcd(b,a%b):a;
}
ll lcm(ll a,ll b){
return a/gcd(a,b)*b;
}
inline int read(){
int s=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-') f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
s=s*10+ch-'0';
ch=getchar();
}
return s*f;
}
const ll mod = 1e9+7;
const int N = 1e5+7;
int a[N];
ll quickPow(ll a, ll b, ll mod) {
ll ans = 1;
while(b) {
if(b&1) ans=(ans*a)%mod;
a=(a*a)%mod;
b>>=1;
}
return ans;
}
void solve(){
ll n;scl(n);
if(n&1) cout<<(quickPow(3,n,mod)%mod-3+mod)%mod*quickPow(4,mod-2,mod)%mod<<endl;
else cout<<(quickPow(3,n,mod)%mod+3+mod)%mod*quickPow(4,mod-2,mod)%mod<<endl;
}
int main(){
//ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#ifdef ONLINE_JUDGE
#else
freopen("in.txt", "r", stdin);
//debug = 1;
#endif
//time_t beg, end;
//if(debug) beg = clock();
int T=1;
while(T--) solve();
/*
if(debug) {
end = clock();
printf("time:%.2fs\n", 1.0 * (end - beg) / CLOCKS_PER_SEC);
}
*/
return 0;
}
Problem.H 异或
题解
第二赛道最有意思的一道题,不过算是经典题(cf上的一道原题)。
前面已经有讲的比较好的题解了,这里就大致说一下这个巧妙的思路,以及怎么去往这个思路想。
首先暴力的做法肯定过不了,然后考虑进行优化,优化的思路需要从
x
+
y
=
a
x+y=a
x+y=a,
x
⨁
y
=
b
x \bigoplus y=b
x⨁y=b这两个方程入手。
异或其实就是不进位的加法,这样就保证了
a
>
=
b
a>=b
a>=b,那么当
a
<
b
a<b
a<b的情况时直接输出
−
1
-1
−1即可。
根据第二个方程我们拆位进行考虑两种情况,
1.当
b
b
b的第
i
i
i位为
1
1
1时,
x
x
x和
y
y
y的第
i
i
i位只能一个为
0
0
0,一个为
1
1
1,因为我们需要保证
x
x
x最小,所以当
b
b
b的第
i
i
i位为
1
1
1时,
x
x
x的第
i
i
i位只能为
0
0
0,
y
y
y的第
i
i
i位只能为
1
1
1。
这时我们可以发现根据第一种情况确定出来的
y
y
y就是
b
b
b,那么
a
−
b
a-b
a−b就是我们在第二种情况需要确定之后的和。
2.当
b
b
b的第
i
i
i位为
0
0
0的情况时,此时由分成了两种情况:
2.1 第
i
i
i位都为
0
0
0。
2.2 第
i
i
i位都为
1
1
1。
这时我们发现只利用第二个方程解决确定不了,我们就需要引入第一个方程进行考虑,在第
i
i
i位都为
0
0
0时,对第一个方程的结果没有影响,在第
i
i
i位都为
1
1
1时,使得第一个方程的结果多了一个
2
i
+
1
2^{i+1}
2i+1。
那么现在问题转换成了给你一个数
c
c
c(等于
a
−
b
a-b
a−b),是否能够选出一些位(第
i
i
i位只能全为
1
1
1或者
0
0
0,全为
1
1
1的情况产生的结果为
2
i
2^{i}
2i),使得这些位凑出来的结果为
c
c
c。
这时可以直接选择贪心从高位往低位放。
也可以选择往下继续找规律。
因为我们每次对答案的贡献都是
2
2
2的次幂。
那么最终
c
c
c肯定需要是一个偶数,对于奇数的情况直接输出-1。
再手推几个数据可以发现
c
2
\frac{c}{2}
2c就是我们求的x。
最后我们就根据确定出来的
x
x
x和
y
y
y判断一下是否符合第二个方程就行了。
代码
#include <bits/stdc++.h>
#define PI atan(1.0)*4
#define rp(i,s,t) for (register int i = (s); i <= (t); i++)
#define RP(i,t,s) for (register int i = (t); i >= (s); i--)
#define sc(x) scanf("%d",&x)
#define scl(x) scanf("%lld",&x)
#define ll long long
#define ull unsigned long long
#define mst(a,b) memset(a,b,sizeof(a))
#define lson rt<<1,l,m
#define rson rt<<1|1,m+1,r
#define pii pair<int,int>
#define pll pair<ll,ll>
#define pil pair<int,ll>
#define m_p make_pair
#define p_b push_back
#define ins insert
#define era erase
#define INF 0x3f3f3f3f
#define inf 0x3f3f3f3f3f3f3f3f
#define dg if(debug)
#define pY puts("YES")
#define pN puts("NO")
#define outval(a) cout << "Debuging...|" << #a << ": " << a << "\n";
#define outval2(a,b) cout << "Debuging...|" << #a << ": " << a <<"\t"<< #b << ": " << b << "\n";
#define outval3(a,b,c) cout << "Debuging...|" << #a << ": " << a <<"\t"<< #b << ": " << b <<"\t"<< #c << ": " << c << "\n";
using namespace std;
int debug = 0;
ll gcd(ll a,ll b){
return b?gcd(b,a%b):a;
}
ll lcm(ll a,ll b){
return a/gcd(a,b)*b;
}
inline int read(){
int s=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-') f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
s=s*10+ch-'0';
ch=getchar();
}
return s*f;
}
void solve(){
ll a,b;cin>>a>>b;
if(a<b){
puts("-1");
return ;
}
ll c=a-b;
if(c&1){
puts("-1");
return ;
}
ll x=c/2;
ll y=a-x;
if((x^y)!=b) puts("-1");
else cout<<x<<" "<<y<<endl;
}
int main(){
//ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#ifdef ONLINE_JUDGE
#else
// freopen("in.txt", "r", stdin);
//debug = 1;
#endif
//time_t beg, end;
//if(debug) beg = clock();
int T=1;
while(T--) solve();
/*
if(debug) {
end = clock();
printf("time:%.2fs\n", 1.0 * (end - beg) / CLOCKS_PER_SEC);
}
*/
return 0;
}
Problem.I Hard Problem I
题解
根据贪心的策略发现直接修改奇数位置的字符最优(下标从 0 0 0开始),那么我们直接枚举奇数位置的字符,如果和前面或者后面的字符相同,那么就直接修改成和相邻字符不同的任意一个其他字符。
代码
#include <bits/stdc++.h>
#define PI atan(1.0)*4
#define rp(i,s,t) for (register int i = (s); i <= (t); i++)
#define RP(i,t,s) for (register int i = (t); i >= (s); i--)
#define sc(x) scanf("%d",&x)
#define scl(x) scanf("%lld",&x)
#define ll long long
#define ull unsigned long long
#define mst(a,b) memset(a,b,sizeof(a))
#define lson rt<<1,l,m
#define rson rt<<1|1,m+1,r
#define pii pair<int,int>
#define pll pair<ll,ll>
#define pil pair<int,ll>
#define m_p make_pair
#define p_b push_back
#define ins insert
#define era erase
#define INF 0x3f3f3f3f
#define inf 0x3f3f3f3f3f3f3f3f
#define dg if(debug)
#define pY puts("YES")
#define pN puts("NO")
#define outval(a) cout << "Debuging...|" << #a << ": " << a << "\n";
#define outval2(a,b) cout << "Debuging...|" << #a << ": " << a <<"\t"<< #b << ": " << b << "\n";
#define outval3(a,b,c) cout << "Debuging...|" << #a << ": " << a <<"\t"<< #b << ": " << b <<"\t"<< #c << ": " << c << "\n";
using namespace std;
int debug = 0;
ll gcd(ll a,ll b){
return b?gcd(b,a%b):a;
}
ll lcm(ll a,ll b){
return a/gcd(a,b)*b;
}
inline int read(){
int s=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-') f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
s=s*10+ch-'0';
ch=getchar();
}
return s*f;
}
const int N = 1e6+7;
struct node{
int pos,op;
}p[N];
void solve(){
string s;cin>>s;
int len=s.size();
int num=0;
rp(i,1,len-1){
if(s[i]==s[i-1]){
if(i!=len-1){
int id1=s[i-1]-'a';
int id2=s[i+1]-'a';
// outval3(i,id1,id2);
rp(j,0,25){
if(j!=id1&&j!=id2){
s[i]=j+'a';
break;
}
}
}
num++;
}
}
// outval(s);
cout<<num<<endl;
}
int main(){
//ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#ifdef ONLINE_JUDGE
#else
freopen("in.txt", "r", stdin);
//debug = 1;
#endif
//time_t beg, end;
//if(debug) beg = clock();
int T=1;
while(T--) solve();
/*
if(debug) {
end = clock();
printf("time:%.2fs\n", 1.0 * (end - beg) / CLOCKS_PER_SEC);
}
*/
return 0;
}
Problem.J 消息传播
题解
手推几个样例可以发现,当
[
2
,
n
+
1
]
[2,n+1]
[2,n+1]中有能整除
k
+
1
k+1
k+1的或者被
k
+
1
k+1
k+1整除的数时输出2,否则输出1。
那么问题就转换成了怎么快速判断
[
2
,
n
+
1
]
[2,n+1]
[2,n+1]中是否存在符合条件的数。
我们把符合条件的数分成两种:
1.被
k
+
1
k+1
k+1整除的数。
2.整除
k
+
1
k+1
k+1的数。
对于第一种情况我们直接判断
2
∗
(
k
+
1
)
2*(k+1)
2∗(k+1)是否小于等于
n
n
n即可,因为
2
∗
(
k
+
1
)
2*(k+1)
2∗(k+1)是最小的被
k
+
1
k+1
k+1整除的数。
对于第二中情况我们直接判断
k
+
1
k+1
k+1是不是质数即可,不是质数的话,根据唯一分解定理,在
[
2
,
n
+
1
]
[2,n+1]
[2,n+1]中肯定存在能够整除
k
+
1
k+1
k+1的数。
代码
#include <bits/stdc++.h>
#define PI atan(1.0)*4
#define rp(i,s,t) for (register int i = (s); i <= (t); i++)
#define RP(i,t,s) for (register int i = (t); i >= (s); i--)
#define sc(x) scanf("%d",&x)
#define scl(x) scanf("%lld",&x)
#define ll long long
#define ull unsigned long long
#define mst(a,b) memset(a,b,sizeof(a))
#define lson rt<<1,l,m
#define rson rt<<1|1,m+1,r
#define pii pair<int,int>
#define pll pair<ll,ll>
#define pil pair<int,ll>
#define m_p make_pair
#define p_b push_back
#define ins insert
#define era erase
#define INF 0x3f3f3f3f
#define inf 0x3f3f3f3f3f3f3f3f
#define dg if(debug)
#define pY puts("YES")
#define pN puts("NO")
#define outval(a) cout << "Debuging...|" << #a << ": " << a << "\n";
#define outval2(a,b) cout << "Debuging...|" << #a << ": " << a <<"\t"<< #b << ": " << b << "\n";
#define outval3(a,b,c) cout << "Debuging...|" << #a << ": " << a <<"\t"<< #b << ": " << b <<"\t"<< #c << ": " << c << "\n";
using namespace std;
int debug = 0;
ll gcd(ll a,ll b){
return b?gcd(b,a%b):a;
}
ll lcm(ll a,ll b){
return a/gcd(a,b)*b;
}
inline int read(){
int s=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-') f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
s=s*10+ch-'0';
ch=getchar();
}
return s*f;
}
int isprime(ll x){
for(ll i=2;i*i<=x;i++) if(x%i==0) return 0;
return 1;
}
void solve(){
ll n,k;scl(n);scl(k);k++;n++;
if(isprime(k)&&k*2>n) puts("1");
else puts("2");
}
int main(){
//ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#ifdef ONLINE_JUDGE
#else
freopen("in.txt", "r", stdin);
//debug = 1;
#endif
//time_t beg, end;
//if(debug) beg = clock();
int T=1;
while(T--) solve();
/*
if(debug) {
end = clock();
printf("time:%.2fs\n", 1.0 * (end - beg) / CLOCKS_PER_SEC);
}
*/
return 0;
}