【2019-总结】初中毕业暑假集训No.6

目录

前言

题目解析

一、Hindex

分析

代码

二、Telefoni

分析

代码

三、Turnir

题目

分析

考试瞎搞代码

AC代码

四、Savrsen

题目

分析

考试瞎搞-暴力超时-过1/4的点-代码

AC代码

五、Sirni

六、Gauss


前言

依然考得很垃圾QAQ...什么时候能晋升一下呀啊啊啊啊


这篇博客本来应该是升高一的那个暑假写的

现在考完CSP正高一的自己写博客时偶然发现了这篇被遗忘已久的博客...

发现当时只写了三和四,于是决定填坑...qwq...(还好当时只剩了两道简单题啊喂!最后两道难题不管了2333)

题目解析

一、Hindex

【2019-总结】初中毕业暑假集训No.6_第1张图片

Sample Input 1

5

1 1 4 8 1

Sample Output 1

2

Sample Input 2

5

8 5 3 4 10

Sample Output 2

4

分析

当过了一个暑假的自己翻出程序包找到自己代码时,

内心os:“woc!好妙啊!我当时的做法怎么那么优秀!”


这道题求一个数H,满足有H篇论文分数不低于H

例如若H=3,那么至少有3篇博客分数不低于3,合法的一种情况:3 1 5 4

可以【贪心】地想,如果一个数越大,那么就能满足更大的H,而且H取决于较小的那个数

于是可以先把所有数从大到小排序,然后循环检查每个数一次判断当前分数是否大于等于 i(i 代表了篇数H)

如果大于等于i,说明当前数满足,更新答案,继续循环

如果小于i,说明从当前到最后的数都不能使H增加了(数列递减),于是退出循环,输出答案

代码

#include
#include
#include
#include
#include
using namespace std;
const int MAXN=5e5;
int c[MAXN+5];
int n,ans;
bool cmp(int a,int b)
{
	return a>b;
}
int main()
{
	//freopen("hindex.in","r",stdin);
	//freopen("hindex.out","w",stdout);
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
		scanf("%d",&c[i]);
	sort(c+1,c+n+1,cmp);
	for(int i=1;i<=n;i++)
	{
		if(i<=c[i])
			ans=max(ans,i);
		else
			break;
	}
	printf("%d\n",ans);
	return 0;
}

二、Telefoni

【2019-总结】初中毕业暑假集训No.6_第2张图片

Sample Input 1

4 1

1 0 1 1

Sample Output 1

1

Sample Input 2

5 2

1 0 0 0 1

Sample Output 2

1

Sample Input 3

8 2

1 1 0 0 1 0 0 1

Sample Output 3

2

分析

当过了一个暑假的自己翻出程序包找到自己代码时,

再次内心os:“woc!好妙啊!我当时的做法怎么那么优秀!”


可以联想一下生活中的wifi信号

如果你走得离信号站越来越远,那么信号会越来越弱,直至没有

如果你又重新到达了一个信号站,那么信号满格

再看这道题,大体思路是差不多的

信号从第一张桌子发出,信号强度往后递减,当信号减至0,就需要接一个电话,信号又变强了

这样一直从头做到尾即可

你可能会想:后面一个电话向前的信号范围可能会与当前信号接通呀?

答:这道题最开始只有第一个电话是有信号的,也就是说当前这个信号到达的位置以后的电话都还不能发出信号

还有一个要点:自己这一电话会占一份信号

代码

#include
#include
#include
#include
#include
using namespace std;
const int MAXN=3e5;
int a[MAXN+5],pre[MAXN+5];
int n,d,cnt,ans;
int main()
{
	//freopen("telefoni.in","r",stdin);
	//freopen("telefoni.out","w",stdout);
	scanf("%d%d",&n,&d);
	for(int i=1;i<=n;i++)
		scanf("%d",&a[i]);
	for(int i=1;i<=n;i++)
	{
		if(a[i]==1)
			cnt=d-1;
		else if(cnt==0)
		{
			ans++;
			cnt=d-1;
		}
		else
			cnt--;
	}
	printf("%d\n",ans);
	return 0;
}

三、Turnir

题目

【2019-总结】初中毕业暑假集训No.6_第3张图片

【2019-总结】初中毕业暑假集训No.6_第4张图片

Sample Input 1


1 4 3 2

Sample Output 1

2 0 1 1

Sample Input 2

4
5 3 2 6 4 8 7 1 2 4 3 3 6 4 8 1

Sample Output 2

1 2 2 1 1 0 1 3 2 1 2 2 1 1 0 3

Sample Input 3

1
1 1

Sample Output 3

0 0

分析

(感觉这道题本来自己离胜利(正解)不远了,但是做着做着就混乱了...要是这道题有分就不至于排名那么惨了.../暴风哭泣)

个人感觉形象一点的说法就是“垫高高”——用较小的或相等的数垫在自己底下,自己就上了一层

把全部数从小到大排序,这样“自己”(当前数)的序号 i 就代表着有多少小于等于自己的数(包含自己)

同时要加入排在当前数后面,但是等于当前数的个数——总共统计小于等于当前数的个数(包含当前数)

记统计后的值为cnt,则当前数对应的答案 = log( 2,cnt )

直白解释:假如小于等于当前数的有:A1,A2,A3...An,那么它们能“垫高”多少层呢,就看能除以多少次2,因为每一层除以2得出新一的层,层数就是n对2取对数(2 ^ (?) = n)

AC代码写的比较巧妙,值得xio习...

考试瞎搞代码

//第二个样例过不了QAQ 
#include
#include
#include
#include
#include
#include
using namespace std;
typedef long long ll;
const int MAXN=105000;
ll a[MAXN+5],b[MAXN+5],tot,Min=0x3f3f3f3f;
int n,cnt,tmp,ans,flag,t,res[MAXN+5];
ll Pow(int x,int y)
{
	ll ret=1;
	while(y--)
		ret*=x;
	return ret;
}
int cal(int x)
{
	int ret=0;
	while(x%2==0)
	{
		ret++;
		x/=2;
	}
	return ret;
}
int main()
{
	freopen("turnir.in","r",stdin);
	freopen("turnir.out","w",stdout);
	scanf("%d",&n);
	ans=n;
	tot=Pow(2,n);
	for(int i=1;i<=tot;i++)
	{
		scanf("%lld",&a[i]);
		b[i]=a[i];
		Min=min(Min,a[i]);
	}
	sort(a+1,a+tot+1);
	cnt=1;
	for(int i=1;i<=tot;i++)
	{
		if(a[i]==a[i+1])
			cnt++;
		else
		{
			tmp=cal(cnt);
			ans=ans-tmp;
			t=ans;
			if(a[i]!=Min)
				ans=min(ans-tmp,ans-1);//有点问题
			ans=max(0,max(ans,t-cal(i)));
			//ans=max(ans,t-cal(i));
			res[a[i]]=ans;
			cnt=1;
		}
		//printf("%lld: cnt:%d tmp:%d ans:%d\n",a[i],cnt,tmp,ans);
	}
	
	for(int i=1;i<=tot;i++)
		if(i==tot)
			printf("%d\n",res[b[i]]);
		else
			printf("%d ",res[b[i]]);
	
	return 0;
}

AC代码

特别鸣谢:03号同学(抱歉,我只知道考号,但不知道你是哪个qwq...)

#include
#include
#include
#include
#include
#include
using namespace std;
typedef long long ll;
const int MAXN=20;
int n,tot,ans[(1<=2)
	{
		ret++;
		x/=2;
	}
	return ret;
}
int main()
{
	//freopen("turnir.in","r",stdin);
	//freopen("turnir.out","w",stdout);
	scanf("%d",&n);
	tot=Pow(2,n);
	for(int i=1;i<=tot;i++)
	{
		scanf("%d",&a[i].num);
		a[i].id=i;
	}
	sort(a+1,a+tot+1,cmp);
	for(int i=1;i<=tot;i++)
	{
		int j=i;
		while(i

四、Savrsen

题目

【2019-总结】初中毕业暑假集训No.6_第5张图片

Sample Input 1

1 9

Sample Output 1

21

Sample Input 2

24 24

Sample Output 2

12

分析

考试评讲后的感受:啊啊啊水题!水水水水水水水!智商被侮辱!怒!(╯‵□′)╯︵┻━┻


过程类似埃氏筛法:

设x(1<=x<=B)的倍数为k(k ≠ x),则 k = 2x,3x,4x...nx(nx<=B),k的因数和就+=x

最后累加答案即可

考试瞎搞-暴力超时-过1/4的点-代码

#include
#include
#include
#include
#include
using namespace std;
typedef long long ll;
const int MAXN=1e7;
int a,b;
ll ans;
ll f(int x)
{
	ll tot=0;
	for(int i=1;i

AC代码

特别鸣谢:CXH同学...qwq...

#include
#include
#include
#include
#include
using namespace std;
typedef long long ll;
const int MAXN=1e7;
int cnt[MAXN+5];
int a,b;
ll ans;
int main()
{
	//freopen("savrsen.in","r",stdin);
	//freopen("savrsen.out","w",stdout);
	scanf("%lld%lld",&a,&b);
	for(int i=1;i<=b;i++)
	{
		int x=i,k=1LL*2*x;
		for(;k<=b;k+=x)
			cnt[k]+=x;
	}
	for(int i=a;i<=b;i++)
		ans+=1LL*abs(i-cnt[i]);
	printf("%lld\n",ans);
	return 0;
}

五、Sirni

【2019-总结】初中毕业暑假集训No.6_第6张图片

Sample Input 1

4

2

6

3

11

Sample Output 1

1

Sample Input 2

4

1

2

3

4

Sample Output 2

0

Sample Input 3

3

4

9

15

Sample Output 3

4

六、Gauss

【2019-总结】初中毕业暑假集训No.6_第7张图片

【2019-总结】初中毕业暑假集训No.6_第8张图片

Sample Input 1

4

1 1 1 1

2

1 2

2

2 5

4 10

1

4 2

Sample Output 1

7

Sample Input 2

3

6 9 4

2

5 7

3

1 1

7 8

6 10

2

6 2

70 68

Sample Output 2

118

-2

Sample Input 3

3

8 3 10

2

8 4

3

1 6

5 1

3 7

2

5 1

3 1

Sample Output 3

16

66

 

你可能感兴趣的:(总结&心得,数学,模拟)