周赛题解(A,B,D,H)

A.

Iroha has a sequence of positive integers A=(A1,A2,…,AN)A=(A1​,A2​,…,AN​) of length N (N≥1N≥1).
She generated a string SS using AA as follows:

  • Start with S=S= |.
  • For i=1,2,…,Ni=1,2,…,N, perform the following operations in order:
    • Append AiAi​ copies of - to the end of SS.
    • Then, append one | to the end of SS.

Given the generated string S, reconstruct the sequence A.

题目描述

        给定一个字符串每一个字串ai是由“|”隔开的,ai表示为两个相邻的|之间有多少个-。分别输出ai。

解题思路

        本题为签到题直接进行暴力搜索就好。

题目代码

#include<bits/stdc++.h>
#define endl "\n"

using namespace std;

string s;
char a = '-',b = '|';

int main()
{
	cin >> s;
	int ans = 0;
	for(int i = 1 ; i < s.size() ; i ++)
	{
		if(s[i] == a)	ans ++;
		else
		{
			cout << ans <<" ";
			ans = 0;
		}
	}
	
	return 0;
 } 

B

题目描述

        青蛙弗雷娅正在二维坐标平面上旅行。她目前位于点 (0,0)(0,0),想要前往点 (x,y)(x,y)。在一次移动中,她选择一个整数 dd,使得 0≤d≤k0≤d≤k,并向她面朝的方向跳跃 dd 个位置。

最初,她面朝正 xx 方向。在每次移动后,她将交替面朝正 x 方向和正 y 方向(即,在她的第二次移动时,她将面朝正 y 方向,在第三次移动时面朝正 x 方向,依此类推)。

她必须执行的最少移动次数是多少,以便落在点 (x,y)(x,y) 上?

解题思路

        本题可知青蛙行进方向为x,y轴正方向交替行进,每次可以前进1-n步,求最小移动次数。根据题意本题的最优解一定是尽可能每一次都走n步知道走不到n步,一次性走完就可以。并且青蛙在x轴上与y轴上的移动次数最多差一次。如果x方向次数 k 大,则总共走2*k -1次。否则为y轴次数的二倍。

题目代码

#include<bits/stdc++.h>
#define LL long long
#define endl "\n"

using namespace std;

int x,y,k,t;


int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	
	cin >> t;
	while(t -- )
	{
		cin >> x >> y >> k;
		int a = (x + k - 1)/k;
		int b = (y + k - 1 )/k;
		if(a > b)	cout << 2*a - 1<<endl;
		else	cout << 2*b << endl;
	 } 
	 
	 return 0;
	
 } 

D.

题目描述

        微博提供了一种便捷的交流平台。一条微博中,可以提及其它用户。例如Lee发出一条微博为:“期末考试顺利 @Kim @Neo”,则Lee提及了Kim和Neo两位用户。

我们收集了N(1 < N < 10000)条微博,并已将其中的用户名提取出来,用小于等于100的正整数表示。

通过分析这些数据,我们希望发现大家的话题焦点人物,即被提及最多的人(题目保证这样的人有且只有一个),并找出那些提及它的人。

解题思路

        可以用vector数组存储提及当前此人的所有人的编号,数组存储当前此人被提及次数,找到最大,提取出来提及此人的人的编号,排序去重,输出就好。

        第二种思路,用二维数组存储信息,i为发布微博的人,j为被提及到的人。每个人计算次数后更新最大依次输出就好。

题目代码

        思路一:

#include<bits/stdc++.h>
#define endl "\n"

using namespace std;

int x[110],f[10010];
int n;
vector<int> d[110];

int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	
	cin >> n;

	while(n -- )
	{
		int a,b;
		cin >> a >> b;
		while(b -- )
		{
			int t;
			cin >> t;
			x[t] ++;
			d[t].push_back(a);
		}
	}
	
	int ans = 0,t;
	for(int i = 1; i <= 100 ; i ++)
		if(ans < x[i])
		{
			ans = x[i];
			t = i;
		}
	cout << t << endl;
	
	int k = 1;
	while(!d[t].empty())
	{
		f[k ++] = d[t].back();
		d[t].pop_back();
	}
	sort(f + 1 , f + k);
	int y = unique(f + 1 , f + k) - f;
	for(int i = 1 ; i < y ; i ++)
		cout << f[i] << " ";
	return 0;
}

        思路二:

#include<bits/stdc++.h>
#define endl "\n"
#define M INT_MIN
using namespace std;

int a[110][110],b[110];//前为发表后为被提及
int t;

int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	
	cin >> t;
	
	while( t -- )
	{
		int x,y;
		cin >> x >> y;
		for(int i = 1 ; i <= y ; i ++)
			{
				int k;
				cin >> k;
				a[x][k] ++;
			}
	}
	
	int ans = M,x;
	for(int i = 1; i <= 100 ; i ++)
	{
		for(int j = 1 ; j <= 100 ; j++)
		{
			b[i] += a[j][i];
		}
		if(ans < b[i])
		{
			ans = b[i];
			x = i;
		}
	}
	
	cout << x << endl;
	
	for(int i = 1; i <= 100 ; i ++)
	{
		if(a[i][x])
			cout << i <<" ";
	}
		
	return 0;
}

H.

题目描述

        你知道什么是``互质序列''吗?它是由n个正整数组成的序列,并且它们的最大公约数(GCD)等于1。
``互质序列''由于其限制条件而容易找到。但是我们可以通过删除恰好一个整数来尝试最大化这些整数的最大公约数。现在给定一个序列,请最大化其元素的最大公约数。

解题思路

        记录数组的前缀GCD,和后缀GCD,最后将去除当前点的前缀和后缀的GCD进行比较,得出最大值,即为答案。

题目代码

        

#include<bits/stdc++.h>
#define LL long long 
#define endl "\n"

using namespace std;
const int N = 1e5 + 10;

int t;
LL a[N],d[N],f[N];

LL gcd(LL a,LL b)
{
	return b == 0 ? a :gcd(b, a%b);
}
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	
	cin >> t;
	while(t -- )
	{
		int n;
		cin >> n;
		for(int i = 1; i <= n ; i ++)
			cin >> a[i];
		
		d[1] = a[1];
		f[n] = a[n];
		for(int i = 2; i <= n ; i ++)
			d[i] = gcd(d[i - 1] , a[i]);
		for(int i = n - 1 ; i > 0 ; i --)
			f[i] = gcd(f[i + 1] , a[i]);
			
		LL ans = 1;
		
		for(int i = 1 ; i <= n ; i ++)
		{
			ans  = max(ans , gcd(f[i + 1] , d[i - 1]));
		}
		
		cout << ans << endl;
	} 
	
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值