赶交题解时间,这场a和d只说思路,代码没A呢都
A. 小妹妹个数 2014新生暑假个人排位赛11
题目描述
喜欢焦叔叔的小妹妹实在是太多了,以至于焦叔叔不得不给她们编号1-N。焦叔叔对于编号为质数的小妹妹有种特别的好感,由于有好感的小妹妹数目太多,焦叔叔自己都数不清楚了,请你来帮忙数一下。
输入格式
多组数据,每行一个正整数N,N不大于1000000000。
数据组数小于15。
输出格式
每行一个数字,有好感的小妹妹数。
输入样例
5
输出样例
3
有技巧的打表,分成根号n块,先找到在哪块里,把之前块的素数和用打表结果弄出来,再爆搜块内有多少小于它的素数。。
(当时一直以为有意想不到的公式,还是太年轻。。)
-----------------------------------------------------------------------------
B. 田田背课文 2014新生暑假个人排位赛11
题目描述
田田被老师要求背诵一个字符串,田田刚刚背了一个子串,说他记性差他还不承认,背下这个子串后却忘了这个子串是从哪里开始的。
现在田田把这个字符串给你,并且让你告诉他至少一次背多长的子串才不可能产生歧义,即不存在另一个子串与它相等
输入格式
输入仅一行,即要求田田背诵的字符串
长度<=10^6
输出格式
输出一行,即不产生歧义串的最小串长
输入样例
abcdabcd
输出样例
5
#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <algorithm>
#define maxn 1000010
using namespace std;
string s;
int t;
char inps[maxn];
void radix(int *str,int *a,int *b,int n,int m)
{
static int count[maxn];
memset(count,0,sizeof(count));
for(int i=0;i<n;++i) ++count[str[a[i] ] ];
for(int i=1;i<=m;++i) count[i]+=count[i-1];
for(int i=n-1;i>=0;--i) b[--count[str[a[i] ] ] ]=a[i];
}
void suffix_array(int *str,int *sa,int n,int m)
{
static int rank[maxn],a[maxn],b[maxn];
for(int i=0;i<n;++i) rank[i]=i;
radix(str,rank,sa,n,m);
rank[sa[0] ]=0;
for(int i=1;i<n;++i) rank[sa[i] ]=rank[sa[i-1] ]+(str[sa[i] ]!=str[sa[i-1] ]);
for(int i=0;1<<i <n;++i)
{
for(int j=0;j<n;++j)
{
a[j]=rank[j]+1;
b[j]=j+(1<<i)>=n?0:rank[j+(1<<i) ]+1;
sa[j]=j;
}
radix(b,sa,rank,n,n);
radix(a,rank,sa,n,n);
rank[sa[0] ]=0;
for(int j=1;j<n;++j)
{
rank[sa[j] ]=rank[sa[j-1] ]+(a[sa[j-1] ]!=a[sa[j] ] || b[sa[j-1] ]!=b[sa[j] ]);
}
}
}
int substr(string str)
{
string rev;
static int s[maxn],sa[maxn],rank[maxn],h[maxn];
int n=str.length();
copy(str.begin(),str.end(),s);
suffix_array(s,sa,n,256);
for(int i=0;i<n;i++) rank[sa[i]]=i;
int k=0;
int ans1=0,pos1=0;
for(int i=0;i<n;++i)
{
k= k==0?0:k-1;
while(rank[i]>0 && s[i+k]==s[sa[rank[i]-1]+k ]) ++k;
h[rank[i] ]=k;
if(h[rank[i] ]>ans1)
{
ans1=h[rank[i] ];
pos1=i;
}
}
return ans1;
}
int main()
{
scanf("%s",inps);
s.assign(inps);
printf("%d\n",substr(s)+1);
return 0;
}
---------------------------------------------------------------------------------
C. 小妹妹采蘑菇 2014新生暑假个人排位赛11
题目描述
在广茂的大森林里居住着一位可爱的小妹妹,以及一位怪叔叔。这天,怪叔叔让小妹妹为他做一锅蘑菇汤,可怜的小妹妹只好出门采集蘑菇。怪叔叔知道,森林里一共有n种不同的蘑菇,所以他提出了一个变态的要求,小妹妹必须为他做一锅包含所有n种蘑菇的汤。也就是说,小妹妹至少要采集齐所有的n种蘑菇。她想知道,平均要采多少朵蘑菇能满足怪叔叔的要求,注意,她每次所采的蘑菇是等概率的。
输入格式
多组case,case<=100。每组case一行一个数n,1<=n<=100。输入以EOF结束。
输出格式
每组case输出一行答案,保留六位小数。
输入样例
1
2
输出样例
1.000000
3.000000
把i从1到n的值加起来就好了~
(错位相减什么的推出来的,我表示高中那玩意儿就没怎么算对过,实在不敢用)
#include <iostream>
#include <cstdio>
using namespace std;
int n;
double ans;
int main()
{
while(~scanf("%d",&n))
{
ans=0;
for(int i=1;i<=n;i++) ans+=((double)n)/((double)i);
printf("%.6lf\n",ans);
}
return 0;
}
-----------------------------------------------------
D. 焦级长的激光炮 2014新生暑假个人排位赛11
题目描述
焦级长特别喜欢设计电脑游戏,他刚刚给他的防御工事设计了一套激光炮防御系统,该系统有N座激光炮,每座可以发射足够束激光炮,但每次只能发射一束。发射时,需要T1秒才能射出,发射后需要T2分钟的冷却时间。每束激光的速度均为V(km/min),并且会沿距离最短的路径去打击目标,为简化问题,计算激光在空中的时间只需将激光炮到目标的水平距离(km)除以V(km/min)即可,单位为分钟。现在给出N座激光炮的坐标,M个敌人的坐标,T1,T2和V,求出至少多少分钟焦级长的防御工事能消灭所有敌人。
输入格式
输入为多组数据,第一行为五个正整数N,M,T1,T2,V,接下来M行每行两个整数代表敌人坐标,接下来N行每行两个整数代表激光炮坐标。
1<=N<=50,1<=M<=50,坐标绝对值不超过10000,T1,T2,V不超过2000。
输出格式
输出一个实数表示最少需要多少分钟才能消灭完所有敌人,四舍五入保留六位小数。
输入样例
3 3 30 20 1
0 0
0 50
50 0
50 50
0 1000
1000 0
输出样例
91.500000
但是,如果炮比敌人少怎么办呢?菊苣教育我们,把炮拆点,打的每炮拆成一个点,共n*m个点,就好了~
-----------------------------------------------------------------
E. 小妹妹去划船 2014新生暑假个人排位赛11
题目描述
小妹妹和叔叔来到了小明湖畔划船,到了湖中间的时候,叔叔突然手一抖就把桨掉到了水里。叔叔对小妹妹说:“怎么办呀我们没办法划船了,我们是不是就只能这样子一直两个人呆在湖中央了呢~?”。 机智的小妹妹想了一会儿,她说:“我发现,靠风来吹我们的船也是可以动的哟~你说风什么时候能把我们吹回码头?” 这下次可难倒叔叔了,请你帮助他解决这个问题好不让小妹妹失望。 叔叔的船现在在sx,sy位置,而码头在ex,ey位置。 我们假设风只向东(E)南(S)西(W)北(N)四个方向吹,且每吹一次风: 东风将船向x+1,y方向吹; 南风将船向x,y-1方向吹; 西风将船向x-1,y方向吹; 北风将船向x,y+1方向吹。 请问叔叔和小妹妹最早什么时间回到码头?注意,小妹妹的船是有锚的~她不希望船动的话叔叔就在第一时间把锚抛下去。
输入格式
输入包含多组数据。每组输入第一行包含五个整数,t,sx,sy,ex,ey,第二行包含t个字符,仅含'E','S','W','N'。
坐标绝对值小于1000000000。t<=100000。输入保证起点重、终点坐标不相同。
输出格式
输出一个t表示最早到达码头的时间,如果到达不了则输出-1。
输入样例
5 0 0 1 1
SESNW
输出样例
4
(开始没看懂题以为那个(x,y+1)只是代表方向向量,wa了后换成了每次移动一格的理解方式,就过了。。)
#include <iostream>
#include <cstdio>
#include <cmath>
#define maxt 100005
using namespace std;
char input[maxt];
int t,sx,sy,ex,ey,ans;
int counting(char dir1,char dir2)
{
int flag1=0,flag2=0;
int i;
for(i=0;i<t;i++)
{
if(input[i]==dir1) flag1++;
if(input[i]==dir2) flag2++;
if(flag1==abs(sy-ey) && flag2==abs(sx-ex)) break;
}
if(i==t) return -1;
else return i+1;
}
int main()
{
while(~scanf("%d%d%d%d%d",&t,&sx,&sy,&ex,&ey))
{
scanf("%s",input);
if(ex>sx)
{
if(ey>sy)
{
ans=counting('N','E');
}
else
{
if(ey==sy)
{
ans=counting('0','E');
}
else
{
ans=counting('S','E');
}
}
}
else
{
if(ex==sx)
{
if(ey>sy)
{
ans=counting('N','0');
}
else
{
if(ey==sy)
{
printf("0\n");
continue;
}
else
{
ans=counting('S','0');
}
}
}
else
{
if(ey>sy)
{
ans=counting('N','W');
}
else
{
if(ey==sy)
{
ans=counting('0','W');
}
else
{
ans=counting('S','W');
}
}
}
}
printf("%d\n",ans);
}
return 0;
}