信息与未来2015真题笔记

[信息与未来 2015] 加数

题目描述

给出一个正整数 nnn,在 nnn 的右边加入 ⌊n2⌋\left\lfloor\dfrac n2\right\rfloor2n,然后在新数的右边
再加入 ⌊⌊n2⌋2⌋\left\lfloor\dfrac{\left\lfloor\dfrac n2\right\rfloor}2\right\rfloor22n,一直这样进行下去,直到加入的数为 000 为止(注意,000 不应当被加入)。

求加数结束后新数的长度。

输入格式

一行一个整数 nnn

输出格式

一行一个整数,为加数结束后新数的长度。

样例 #1

样例输入 #1

37

样例输出 #1

8

提示

样例解释

  • ⌊372⌋=18\left\lfloor\dfrac{37}2\right\rfloor=18237=18,加到 nnn 的右边成为 371837183718
  • ⌊182⌋=9\left\lfloor\dfrac{18}2\right\rfloor=9218=9,加到新数的右边成为 371893718937189
  • ⌊92⌋=4\left\lfloor\dfrac{9}2\right\rfloor=429=4,加到新数的右边成为 371894371894371894
  • ⌊42⌋=2\left\lfloor\dfrac{4}2\right\rfloor=224=2,加到新数的右边成为 371894237189423718942
  • ⌊22⌋=1\left\lfloor\dfrac{2}2\right\rfloor=122=1,加到新数的右边成为 371894213718942137189421
  • ⌊12⌋=0\left\lfloor\dfrac12\right\rfloor=021=0,加数结束,最后得到的数是一个 888 位数。

数据范围

1≤n≤1051\le n\le10^51n105

思路

直接模拟,判断位数。

代码

#include <bits/stdc++.h>
//#define int long long
using namespace std;

int n; 
int sum;

void solve()
{
	cin >> n;
	while (n)
	{
		int m = n,num = 0;
		while (m)
			m /= 10,num++;
		sum += num;
		n /= 2;
	}
	cout << sum;
}

signed main()
{
	solve();
	return 0;
}

[信息与未来 2015] 中间值

题目描述

给出一个正整数 nnn,生成长度为 nnn 的数列 aaa,其中 ai=i(1≤i≤n)a_i=i(1\le i\le n)ai=i(1in)

  • nnn 为奇数,则输出 aaa 的中间数(位于 aaa 正中位置的数);
  • nnn 为偶数,则输出位于 aaa 中间两个数的和。

输入格式

一个正整数 nnn

输出格式

一个正整数。若 nnn 为奇数,则输出其中间值;若 nnn 为偶数,则输出两个中间值的和。

样例 #1

样例输入 #1

9

样例输出 #1

5

样例 #2

样例输入 #2

10

样例输出 #2

11

提示

1≤n≤10181\le n\le10^{18}1n1018

思路

nnn 为奇数,则答案为 n÷2+1n\div2+1n÷2+1
nnn 为偶数,则答案为 n+1n+1n+1

代码

#include <bits/stdc++.h>
#define int long long
using namespace std;

int n;

void solve()
{
	cin >> n;
	if (n % 2)
		cout << n/2+1;
	else
		cout << n+1;
}

signed main()
{
	solve();
	return 0;
}

[信息与未来 2015] 买木头

题目描述

nnn 个木材供应商,每个供应商有长度相同的一定数量的木头。长木头可以锯短,但短木头不能接长。有一个客人要求 mmm 根长度相同的木头,要求计算出:此时供货商提供的木头满足客人要求的最大长度是多少。

例如 n=2,m=30n=2,m=30n=2,m=30,两个供货商的木头为:

  • 12,1012,1012,10(第 111 个供货商的木头长度为 121212,共有 101010 根);
  • 5,105,105,10(第 222 个供货商的木头长度为 555,共有 101010 根)。

计算的结果为 555,即长度为 121212 的木头一根可锯出两根长度为 555 的木头,多余的无用;长度为 555 的木头不动,此时,可以得到 303030 根长度为 555 的木头。

输入格式

一行四个整数 n,m,l1,s1n,m,l_1,s_1n,m,l1,s1。其中 l1l_1l1 是第一个供货商木头的长度,s1s_1s1 是第一个供货商木头的数量。其他供货商木头
的长度和数量 lil_ilisi(i≥2)s_i(i\ge2)si(i2)由下面的公式给出:

  • li=((li−1×37011+10193) mod 10000)+1l_i=((l_{i-1}\times37011+10193) \bmod 10000)+1li=((li1×37011+10193)mod10000)+1
  • si=((si−1×73011+24793) mod 100)+1s_i=((s_{i-1}\times73011+24793) \bmod 100)+1si=((si1×73011+24793)mod100)+1

输出格式

一个整数,即满足要求的 mmm 根长度相同的木头的最大长度。

样例 #1

样例输入 #1

10 10000 8 20

样例输出 #1

201

提示

1≤n≤104,1≤m≤106,1≤l1≤104,1≤s1≤1001\le n\le10^4,1\le m\le10^6,1\le l_1\le10^4, 1\le s_1\le1001n104,1m106,1l1104,1s1100

思路

二分木头的长度,每次 check 判断数量是否足够。

代码

#include <bits/stdc++.h>
#define int long long
using namespace std;

int n,m;
int a[10010],b[10010];

bool judge(int x)
{
	int sum = 0;
	for (int i = 1;i <= n;i++)
		sum += a[i]/x*b[i];
	return sum >= m;
}

void solve()
{
	cin >> n >> m >> a[1] >> b[1];
	for (int i = 2;i <= n;i++)
		a[i] = ((a[i-1]*37011+10193)%10000) + 1;
	for (int i = 2;i <= n;i++)
		b[i] = ((b[i-1]*73011+24793)%100) + 1;
	int l = 1,r = 10000,best;
	while (l <= r)
	{
		int mid = (l+r)/2;
		if (judge(mid))
			best = mid,l = mid+1;
		else
			r = mid-1;
	}
	cout << best;
}

signed main()
{
	solve();
	return 0;
}

[信息与未来 2015] 拴奶牛

题目描述

nnn 头奶牛,有 kkk 个木桩,每个木桩有一个位置,一个木桩上只能拴一头奶牛。由于奶牛好斗,所以在拴奶牛的时候,要求距离最近的奶牛的距离尽可能大。

例如 n=4,k=6n=4,k=6n=4,k=6,木桩的位置为 0,3,4,7,8,90,3,4,7,8,90,3,4,7,8,9,此时为下图。
KaTeX parse error: Unexpected end of input in a macro argument, expected '}' at position 12: \underline\̲t̲e̲x̲t̲{\qquad O\quad …
有许多种拴牛方案,例如:

  • 0,3,4,90,3,4,90,3,4,9:此时最近距离为 1113,43,43,4 之间);
  • 0,3,7,90,3,7,90,3,7,9:此时最近距离为 222

输入格式

三个整数 n,k,p1n,k,p_1n,k,p1,其中 p1p_1p1 为第 111 个木桩的位置,其他木桩 pi(i≥2)p_i(i\ge2)pi(i2) 的位置由下面公式给出:

pi=pi−1+((pi−1×2357+137) mod 10)+1p_i = p_{i-1} + ((p_{i-1}\times2357+137) \bmod 10)+1pi=pi1+((pi1×2357+137)mod10)+1

输出格式

一个整数,即奶牛间最近距离的最大值。

样例 #1

样例输入 #1

25 70 99

样例输出 #1

12

提示

1≤n≤k≤106,0≤p1≤1001\le n\le k\le10^6,0\le p_1\le1001nk106,0p1100

思路

二分两只牛之间的距离,每次 check 判断木桩是否足够。

代码

#include <bits/stdc++.h>
#define int long long
using namespace std;

int n,m;
int a[1000010];

bool judge(int x)
{
	int last = 1,num = 1;
	for (int i = 2;i <= m;i++)
		if (a[i]-a[last] >= x)
			num++,last = i;
	return num >= n;
}

void solve()
{
	cin >> n >> m >> a[1];
	for (int i = 2;i <= m;i++)
		a[i] = a[i-1] + ((a[i-1]*2357+137) % 10) + 1;
	int l = 1,r = 1e9,best;
	while (l <= r)
	{
		int mid = (l+r)/2;
		if (judge(mid))
			best = mid,l = mid+1;
		else
			r = mid-1;
	}
	cout << best;
}

signed main()
{
	solve();
	return 0;
}

[信息与未来 2015] 分数计数

题目描述

nnn 个球队,编号为 1∼n1\sim n1n,共进行 nnn 场比赛,每场比赛有一个胜队。计分方法如下:

  • 是连胜中的第一次胜利,则本次胜利得 111 分。
  • 是连胜中的第二次胜利,则本次胜利得 222 分。
  • 是连胜中的第三次胜利,则本次胜利得 333 分。
  • 连胜超过三次以上的胜场,每场得 333 分。

例如 n=12n=12n=12,比赛的胜队为 1,2,1,1,3,2,1,1,1,1,4,21,2,1,1,3,2,1,1,1,1,4,21,2,1,1,3,2,1,1,1,1,4,2,计分如下:

  • 1111+1+2+1+2+3+3=131+1+2+1+2+3+3=131+1+2+1+2+3+3=13 分;
  • 2221+1+1=31+1+1=31+1+1=3 分;
  • 3∼43\sim 434111 分。
  • 5∼125\sim 12512000 分。

求得分最多的队伍的分数。

输入格式

两个整数 n,x1n,x_1n,x1nnn 为球队数,x1x_1x1 为第一次胜队号,第 i(i≥2)i(i\ge2)i(i2) 场比赛胜队的编号由
以下公式确定:

xi=((xi−1×3703+1047) mod n)+1x_i = ((x_{i-1}\times 3703+1047) \bmod n)+1xi=((xi1×3703+1047)modn)+1

输出格式

一个整数,即得分最多队的分数。

样例 #1

样例输入 #1

10 5

样例输出 #1

3

提示

1≤x1≤n≤1061\le x_1\le n\le10^61x1n106

思路

按照题目要求模拟。

代码

#include <bits/stdc++.h>
#define int long long
using namespace std;

int n;
int a[1000010],sum[1000010];

void solve()
{
	cin >> n >> a[1];
	for (int i = 2;i <= n;i++)
		a[i] = ((a[i-1]*3703+1047)%n) + 1;
	int now = 0;
	for (int i = 1;i <= n;i++)
	{
		if (a[i] == a[i-1])
			now++;
		else
			now = 1;
		if (now >= 3)
			sum[a[i]] += 3;
		else
			sum[a[i]] += now;
	}
	int mx = 0;
	for (int i = 1;i <= n;i++)
		mx = max(mx,sum[i]);
	cout << mx; 
}

signed main()
{
	solve();
	return 0;
}

[信息与未来 2015] 求回文数

题目描述

一个正整数,正读和反读都相同的数为回文数,例如 22,131,2442,37073,6,⋯22,131,2442,37073,6,\cdots22,131,2442,37073,6,。所有的 111 位数都是回文数。

现给出一个正整数 nnn,求出 [1,n][1,n][1,n] 中的回文数的个数。

输入格式

一个整数 nnn

输出格式

一个整数,即 1∼n1\sim n1n 中全部回文数的个数。

样例 #1

样例输入 #1

24

样例输出 #1

11

提示

样例解释

111242424 中,回文数有 1∼9,11,221\sim 9,11,2219,11,22,共 111111 个。

数据范围

1≤n≤1041\le n\le10^41n104

思路

枚举。从 111 枚举到 nnn,然后判断是否为回文数。

代码

#include <bits/stdc++.h>
#define int long long
using namespace std;

int n;
int sum;

bool judge(int x)
{
	int y = x,numa = 0;
	while (y)
		numa = numa*10+y%10,y /= 10;
	if (numa == x)
		return true;
	return false;
}

void solve()
{
	cin >> n;
	for (int i = 1;i <= n;i++)
		if (judge(i))
			sum++;
	cout << sum;
}

signed main()
{
	solve();
	return 0;
}

[信息与未来 2015] 连续数的和

题目描述

给出两个整数 nnnkkk,求出 1∼n1\sim n1n 中连续 kkk 个数的和为完全平方数的个数。

输入格式

一行两个整数 n,kn,kn,k

输出格式

一行一个整数,即 1∼n1\sim n1n 中连续 kkk 个数的和为平方数的个数。

样例 #1

样例输入 #1

10 3

样例输出 #1

1

提示

样例解释

1∼101\sim10110 中,连续 333 个数的和有:

  • 1+2+3=61+2+3=61+2+3=6
  • 2+3+4=9=322+3+4=9=3^22+3+4=9=32
  • 3+4+5=123+4+5=123+4+5=12
  • 4+5+6=154+5+6=154+5+6=15
  • 5+6+7=185+6+7=185+6+7=18
  • 6+7+8=216+7+8=216+7+8=21
  • 7+8+9=247+8+9=247+8+9=24
  • 8+9+10=278+9+10=278+9+10=27

故只有 111 个。

数据范围

2≤n≤7×104,1≤k≤n2\le n\le 7\times 10^4,1\le k\le n2n7×104,1kn

思路

枚举所有情况,判断是否为平方数。

代码

#include <bits/stdc++.h>
#define int long long
using namespace std;

void solve()
{
	int n,k;
	cin >> n >> k;
	int now = (1+k)*k/2,sum = 0;
	for (int i = k;i <= n;i++)
	{
		if ((int)(sqrt(now))*(int)(sqrt(now)) == now)
			sum++;
		now -= (i-k+1);
		now += i+1;
	}
	cout << sum;
}

signed main()
{
	solve();
	return 0;
}

[信息与未来 2015] 夏令营小旗手

题目描述

201520152015 年江苏省“信息与未来”小学夏令营在洪泽县实验小学进行,组委会决定在洪泽实验小学的学生中挑选一名小旗手,推选方法如下:

洪泽实验小学有 nnn 名学生,每名学生有一个学号,学号为 1∼n1\sim n1n。同时,每名同学有一张选票,可以推选一名同学为小旗手,最后,得票最多者当选;若得票最有多名(票数相同),则学号小者当选。

例如 n=8n=8n=8,选票为 2,3,4,4,3,4,1,62,3,4,4,3,4,1,62,3,4,4,3,4,1,6444 号学生得票最多(333 票),当选小旗手。

输入格式

两个整数 n,x1n,x_1n,x1nnn 为学生数,x1x_1x1 为第一个选票上的学号,之后的选票 xi(i≥2)x_i(i\ge2)xi(i2) 由下面的递推关系给出:

xi=((xi−1×37+33031) mod n)+1x_i = ((x_{i-1}\times 37+33031)\bmod n)+1xi=((xi1×37+33031)modn)+1

其中  mod \bmodmod 为取余运算。例如,13 mod 8=5,21 mod 21=013 \bmod 8 = 5,21 \bmod 21 = 013mod8=5,21mod21=0。根据这个公式,就能从 x1x_1x1 推出 x2∼nx_{2\sim n}x2n

输出格式

一个整数,即选出的小旗手的学号。

样例 #1

样例输入 #1

5 2

样例输出 #1

2

提示

样例解释

x={2,1,4,5,2}x=\{2,1,4,5,2\}x={2,1,4,5,2}222 号选手票数最多。

数据范围

1≤x1≤n≤1031\le x_1\le n\le10^31x1n103

思路

先算出每个人的投票,然后用 vis 记录求出最大值。

代码

#include <bits/stdc++.h>
#define int long long
using namespace std;

int vis[1010];

void solve()
{
	int n,m;
	cin >> n >> m;
	vis[m]++;
	for (int i = 2;i <= n;i++)
	{
		m = ((m*37 + 33031)%n) + 1;
		vis[m]++;
	}
	int mx = 0,pos = 0;
	for (int i = 1;i <= n;i++)
		if (mx < vis[i])
		{
			mx = vis[i];
			pos = i;
		}
	cout << pos;
}

signed main()
{
	solve();
	return 0;
}
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值