前言
题目解析
一、Hindex
分析
代码
二、Telefoni
分析
代码
三、Turnir
题目
分析
考试瞎搞代码
AC代码
四、Savrsen
题目
分析
考试瞎搞-暴力超时-过1/4的点-代码
AC代码
五、Sirni
六、Gauss
依然考得很垃圾QAQ...什么时候能晋升一下呀啊啊啊啊
这篇博客本来应该是升高一的那个暑假写的
现在考完CSP正高一的自己写博客时偶然发现了这篇被遗忘已久的博客...
发现当时只写了三和四,于是决定填坑...qwq...(还好当时只剩了两道简单题啊喂!最后两道难题不管了2333)
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;
}
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;
}
Sample Input 1
2
1 4 3 2Sample 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 1Sample Output 2
1 2 2 1 1 0 1 3 2 1 2 2 1 1 0 3
Sample Input 3
1
1 1Sample 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;
}
特别鸣谢: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
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
最后累加答案即可
#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
特别鸣谢: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;
}
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
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