CodeTON Round 9 (Div. 1 + Div. 2)

CodeTON Round 9 (Div. 1 + Div. 2) 总结

A

自己推一下就能出来的,输出奇数即可。

因为要递增,所以尽可能取小的数字。

  • i=1,余数肯定是 0,尽可能小,所以 a1=1
  • i=2,余数尽可能小且不重,是 1,所以 a1=1+2=3
  • i=3,余数为 2a3=2+3=5

这样推导后知道 ai=2×i+1

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <vector>
#include <queue>
#include <map>

using namespace std;
typedef long long ll;
const int N=55;
int n;
void solve()
{
    cin>>n;
	for(int i=1;i<=n;i++) cout<<i*2-1<<' ';
    cout<<'\n';
}
int main ()
{
    #ifndef ONLINE_JUDGE
    freopen("1.in","r",stdin);
    freopen("1.out","w",stdout);
    #endif 
    ios::sync_with_stdio(0);
    cin.tie(0);cout.tie(0);
    int T;
    cin>>T;
    while(T--) solve();
    return 0;
}

B

肯定是往数量少的考虑。

f(t) 为偶数,以 t 的大小为依据分类讨论。设 |t| 为字符串 t 的大小。

  • |t|=1,显然只有一个非空子串。
  • |t|=2
    • 当两个字符不同时,一定有三个子串,不符。
    • 当两个字符相同时,会有两个不同的子串,符合题意。
  • |t|=3。只有三个字符都不同时,才会有 6 个不同的子串。

所以就是找连续的三个不同的字符或者两个相同的字符。这样思考一下,只有出现类似于 ababababa 这样的字符才没有子串符合条件。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <vector>
#include <queue>
#include <map>

using namespace std;
typedef long long ll;
const int N=1e5+5;
string s;
void solve()
{
    cin>>s;
    int n=s.size();
    for(int i=0;i<n-2;i++)
        if(s[i]!=s[i+1]&&s[i]!=s[i+2]&&s[i+1]!=s[i+2])
        {
            cout<<s[i]<<s[i+1]<<s[i+2]<<'\n';
            return ;
        }
    for(int i=0;i<n-1;i++) 
        if(s[i]==s[i+1])
        {
            cout<<s[i]<<s[i+1]<<'\n';
            return ;
        }
    cout<<-1<<'\n';
}
int main ()
{
    #ifndef ONLINE_JUDGE
    freopen("1.in","r",stdin);
    freopen("1.out","w",stdout);
    #endif 
    ios::sync_with_stdio(0);
    cin.tie(0);cout.tie(0);
    int T;
    cin>>T;
    while(T--) solve();
    return 0;
}

C1

C 题都用到了一个性质,按位异或可以看作是不进位的加法。设 y>x,就有 yx[yx,y+x]

因此当 y>2x 时,yx>x,因此 yx 不可能是 x 的因数。
y>2x,也有 x<y2yx>y2,又因为 x1,所以 yxy ,所以也不可能是 y 的因数。

所以 y[1,min(2x,m)] 时才会产生贡献。暴力枚举判断即可。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <vector>
#include <queue>
#include <map>

using namespace std;
typedef long long ll;
const int N=1;
int x;
ll m;
void solve()
{
    cin>>x>>m;
    ll n=1,cnt=0;
    while(n<=x) n<<=1;
    for(int y=1;y<=min(n-1,m);y++) 
    {
        int t=x^y;
        if(t==0) continue;
        if(x%t==0||y%t==0) cnt++;
    }
    cout<<cnt<<'\n';
}
int main ()
{
    #ifndef ONLINE_JUDGE
    freopen("1.in","r",stdin);
    freopen("1.out","w",stdout);
    #endif 
    ios::sync_with_stdio(0);
    cin.tie(0);cout.tie(0);
    int T;
    cin>>T;
    while(T--) solve();
    return 0;
}

C2

可以先打表找规律,发现小于 m 的几乎所有 x 的倍数都满足。

t=xy,先考虑,ty 的倍数。
按位异或可以看作是不进位的加法,所以当 x<y 时,t<y+x=2y,而因为 x1tyy 的最小倍数为 2y。所有当 x<y 时,t 不可能是 y 的倍数。
所以只考虑 yxx 较小,暴力枚举 y 判断即可。

再考虑 tx 的倍数。y=xt,因为 xtx+t,所以 x+tm 时,ym。所以 tmxtx 的倍数时都符合题意。但要注意当 t=x 时,y=0,该情况要舍去。还有因为 t=0 时,y=x,这种情况会在考虑 ty 的倍数被计算,所有也没有必要重复算。

txtx,若 tx>m,则有 y=tx>m,不符。所以 t>m+x 时没有贡献。

还剩下一段区间为 [mx,m+x),最多产生两个 x 的倍数,判断一下 y 是否大于 x 且小于等于 m 即可。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <vector>
#include <queue>
#include <map>

using namespace std;
typedef long long ll;
const int N=1;
ll x,m;

void solve()
{
    cin>>x>>m;
    ll ans=0,t;
	if(m>x)
	{
		ans+=max((m-x)/x-1,0ll);
		t=m/x*x;
		ll y=x^t;
		if(y>x&&y<=m) ans++;
		t+=x,y=x^t;
		if(y>x&&y<=m) ans++;
	}
    for(int y=1;y<=min(x,m);y++)
    {
        t=x^y;
        if(t%y==0) ans++;
    }
    cout<<ans<<'\n';
}
int main ()
{
    #ifndef ONLINE_JUDGE
    freopen("1.in","r",stdin);
    freopen("1.out","w",stdout);
    #endif 
    ios::sync_with_stdio(0);
    cin.tie(0);cout.tie(0);
    int T;
    cin>>T;
    while(T--) solve();
    return 0;
}

D

感觉上比 C2 简单。

先转变下条件,若 gcd(i,j)=i,即 ij 的因数,式子就变为 aigcd(ai,aj),1i<jn,其中 ji 的倍数。

开始构造,将 s 从大到小排序。

  • i=1,所以 2jn 的所有 j 都有 aigcd(ai,aj),所以不妨让 a1 为最大,为 s1。然后 2jn 的所有 aj 都不能是 s1
  • i=2,确定为 s2,能影响到 a4,a6,a8,,这些都不能是 s2
  • i=3,可以为 s2,影响到 a6,a9,a12,,这些不能是 s2
  • a4 可以为 s3a5 可以为 s2a6 可以为 s3

就这么推下去,找到 ai 可以取的最大的 sj。若超出 m,就肯定无解。

枚举次数为 n1+n2+n3++nnnlog(n),所以时间复杂度为 O(nlog(n))

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <vector>
#include <queue>
#include <map>

using namespace std;
typedef long long ll;
const int N=1e5+5;
int n,m;
int s[N],a[N];
bool cmp(int x,int y)
{
	return x>y;
}
void solve()
{
	cin>>n>>m;
	for(int i=1;i<=m;i++) cin>>s[i];
	sort(s+1,s+m+1,cmp);
	for(int i=1;i<=n;i++) a[i]=0;
	a[1]=1;
	int mx=0;
	for(int i=1;i<=n;i++)
		for(int j=i*2;j<=n;j+=i)
		{
			a[j]=max(a[j],a[i]+1);
			mx=max(mx,a[j]);
		}
	if(mx>m)
	{
		cout<<-1<<'\n';
		return ;
	}
	for(int i=1;i<=n;i++) cout<<s[a[i]]<<' ';
	cout<<'\n';
}
int main ()
{
	#ifndef ONLINE_JUDGE
	freopen("1.in","r",stdin);
	freopen("1.out","w",stdout);
	#endif 
	ios::sync_with_stdio(0);
	cin.tie(0);cout.tie(0);
	int T;
	cin>>T;
	while(T--) solve();
	return 0;
}

posted @   zhouruoheng  阅读(20)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
· AI 智能体引爆开源社区「GitHub 热点速览」
点击右上角即可分享
微信分享提示