2018西安电子科大同步赛

 

题目描述

 不愤不启不悱不发,王萌萌为了能够成功上研,开始刻苦背GRE单词,但是由于她过于刻苦,在背会英语单词的同时,把中文读音忘了。于是王萌萌又开始复习起中文发音,她先从数字开始复习起。。。
题目很简单,王萌萌给出在[0, 10]范围内的整数的英文单词,你教她中文发音。

输入描述:

第一行输入一个T,表示王萌萌询问的单词。(T <= 20)
后面T行每行一个英文单词,题目保证英文单词是[0, 10]数字所表示的单词且单词书写无误,单词用小写形式给出。

输出描述:

对于每一个输入的单词,输出它的中文读音,请用小写形式给出。
示例1

输入

5
zero
one
one
four
eight

输出

ling
yi
yi
si
ba


水题。

 1 #include<bits/stdc++.h>
 2 #define clr(x) memset(x,0,sizeof(x))
 3 using namespace std;
 4 string e[11]={"zero","one","two","three","four","five","six","seven","eight","nine","ten"};
 5 string c[11]={"ling","yi","er","san","si","wu","liu","qi","ba","jiu","shi"};
 6 map<string,string> etoc;
 7 string s;
 8 int n;
 9 int main()
10 {
11     for(int i=0;i<=10;i++)
12         etoc[e[i]]=c[i];
13     ios::sync_with_stdio(false);
14     cin>>n;
15     for(int i=1;i<=n;i++)
16     {
17         cin>>s;
18         cout<<etoc[s]<<endl;
19     }
20     return 0;
21 }
View Code

 

题目描述

有一款英语练习游戏是这样的,每次会给出一些字母,然后需要你从中拼出一个最长的英文单词。
虽然williamchen的英语非常差,但是他现在搞到了一本英语词典,他只需要在词典里找出一个最长的符合条件的字母即可。
现在你需要写一个程序来帮助他完成这个任务。

输入描述:

包含多组测试数据,每组数据开始一行包含不超过20个字母,表示游戏给出的字母。
接下来是一行一个数字N(1 <= N <= 1000)
接下来N行,每行一个字符串表示词典中的单词,单词长度不会超过10。

输出描述:

每组数据输出一行,表示最长可能拼出的单词长度,如果一个单词都拼不出,那就输出0。
示例1

输入

masterblodpo
7
boogie
magnolia
punch
blood
master
inherent
phantom
ablderrivala
5
arrival
blade
runner
incendies
sicario

输出

6
7

水题。

 1 #include<bits/stdc++.h>
 2 #define clr(x) memset(x,0,sizeof(x))
 3 using namespace std;
 4 const int N=1e2+10;
 5 const int type=26;
 6 char s[N];
 7 int num[type],sum[type];
 8 int n,m,ans;
 9 int main()
10 {
11     while(scanf("%s",s)!=EOF)
12     {
13         ans=0;
14         clr(num);
15         for(int i=0;s[i];i++)
16             num[s[i]-'a']++;
17         scanf("%d",&n);
18         for(int i=1;i<=n;i++)
19         {
20             scanf("%s",s);
21             clr(sum);
22             for(int j=0;s[j];j++)
23                 sum[s[j]-'a']++;
24             int j;
25             for(j=0;j<type;j++)
26                 if(sum[j]>num[j])
27                     break;
28             if(j==type)
29                 ans=max(ans,(int)strlen(s));
30         }
31         printf("%d\n",ans);
32     }
33     return 0;
34 }
View Code

 

题目描述

Arch0n老师is a rich man, 他靠自己的才华和智商年纪轻轻就赚了不少钱。为了训练自己的智商,他经常玩一些interesting的游戏来训练自己的智商,比如什么RGB游戏,还有和妹子一块玩Don't Starve。言归正传,今天他又发明了一个新的interesting game。

Ar老师手上有一堆卡牌,然后卡牌上写了一个数字Ai(正整数),当前他有n张牌,然后他总是随机取出两张来,然后他一眼就能看出这两牌中哪一张小(相同就取相同的,这操作好像对于Ar老师来说太简单了),作为这两张牌的有效分值,然后呢他陷入了沉思,对于n张牌取两张牌显然有确定的组合可能性,有n*(n-1)/2对组合,然后他想知道所有这些组合中第k大的分值是多少。

输入描述:

输入一个t表示数据组数;(0<t<=10)
接下来一行是n,k,表示n张牌和最后第k大的分值;(1<n<2500,保证0<k<=n*(n-1)/2)
接下来一行是n个值ai,表示第i张牌上的数字(0 < ai <= 10000000)。

输出描述:

每组数据输出一行,即第k大的分值为多少。


水题。不过被输出格式lld坑到了,习惯用的I64d竟然不算过。。。。

 1 #include<bits/stdc++.h>
 2 #define clr(x) memset(x,0,sizeof(x))
 3 using namespace std;
 4 const int N=5e3+10;
 5 int a[N];
 6 int n,k,m,T,t;
 7 int main()
 8 {
 9     scanf("%d",&T);
10     while(T--)
11     {
12         scanf("%d%d",&n,&k);
13         for(int i=1;i<=n;i++)
14             scanf("%d",a+i);
15         sort(a+1,a+n+1);
16         t=n;
17         k=n*(n-1)/2-k+1;
18         int i;
19         for(i=1;i<=n;i++)
20         {
21             t--;
22             k-=t;
23             if(k<=0)
24                 break;
25         }
26         printf("%d\n",a[i]);
27     }
28     return 0;
29 }
View Code

题目描述

现在有n个数,每次随机取出两个数x,y,然后加入一个数为(x+y)/2,问最后剩下的那个数的期望是多少?

输入描述:

有多组输入数据,第一行为一个数字T,代表有T组输入数据 (0<T≤20)。
接下来为T组数据。
每组测试数据分2行:
第一行为n,表示有n个数(1≤n≤100)
接下来的一行有n个正整数ai,表示初始的n个数(1≤ai≤10000,1≤i≤n)。

输出描述:

对于每组数据,在一行上输出最后剩下数的期望值的整数部分。
示例1

输入

2
3
1 1 1
2
2 3

输出

1
2

瞎jb猜结论题,结论就是Σai/n。感兴趣的话可以自己证明下。证明思路就是算每个数除以2的次数的概率,然后算出每个数在对应除以2的概率下的除以2出来的数的期望的和。因为你拿两个数相加/2就相当于各自/2。不过这道题很人性,忽略小数点后于是就有这样的结论了。

 1 #include<bits/stdc++.h>
 2 #define clr(x) memset(x,0,sizeof(x))
 3 using namespace std;
 4 const int N=5e3+10;
 5 int n,k,m,T,t;
 6 int main()
 7 {
 8     scanf("%d",&T);
 9     while(T--)
10     {
11         m=0;
12         scanf("%d",&n);
13         for(int i=1;i<=n;i++)
14         {
15              scanf("%d",&t);
16              m+=t;
17         }
18         printf("%d\n",m/n);
19     }
20     return 0;
21 }
View Code

 

题目描述

众所周知,Xieldy最常用的口令是******。
为了改变这一现状,他random了一个01串,并从中截取了一段作为自己的口令。
他选择的口令满足以下条件:
1. 口令串表示的二进制数在十进制下可以被表示为3k(k>=0)。
2. 口令串可以有前导零。
现已经random出了01串,他想知道有多少种口令方案可以选择(不同的子段即为不同)。

输入描述:

若干组数据,每组数据仅一行01串s,表示random出来的的串,|s|<=1e6。

输出描述:

输出口令的方案数。

 

首先用hash的想法做这题。我们从最低位反向求s[n-1]~s[i]的01串%3的值,对应hashed[i]。那么任意一串可以表示为(hashed[h]-hashed[t-1])/2^(n-t) %3,h为串头位置,t为串尾位置,2^(n-t)即为他要把整个值左移n-t位。模3意义下为0即为3k。

然后我们发觉2对3的逆元还是2。那么除以2就相当于乘以2。假如一个数不为0,它在%3下乘2它会始终是2,1,2,1,2,1这样的循环。因此我们上式中要求hashed[h]和hashed[t-1]相同,不然相减后的数永不可能为0.也就永远不能表示为3k。

所以我们统计下各个不同hashed值i的位置数num[i](包括第n位hashed为0),那么不同i对答案的贡献为任意选俩该数值的位置的数量,即num[i]*(num[i]-1)/2。

 1 #include<bits/stdc++.h>
 2 #define clr(x) memset(x,0,sizeof(x))
 3 #define LL long long
 4 using namespace std;
 5 const int N=1e6+10;
 6 int n,m,p;
 7 LL ans;
 8 char s[N];
 9 int  hashed[N];
10 int  num[3];
11 int main()
12 {
13     while(scanf("%s",s)!=EOF)
14     {
15         n=strlen(s);
16         m=0;
17         for(int i=n-1;i>=0;i--)
18         {
19             p=s[i]-'0';
20             p=((n-1-i)&1)?p:(2*p%3);
21             m=(m+p)%3;
22             hashed[i]=m;
23         }
24         hashed[n]=0;
25         clr(num);
26         for(int i=n;i>=0;i--)
27             num[hashed[i]]++;
28         ans=0;
29         for(int i=0;i<3;i++)
30             if(num[i]>1) ans+=1LL*num[i]*(num[i]-1)/2;
31         printf("%lld\n",ans);
32     }
33     return 0;
34 }
View Code

 

题目描述

在学习Operating System的过程中,Glory遇到了这样一个问题,现在有一个大小为可以容纳N个页面的内存,硬盘内的内容被分成M个页面,用1~M来标识,一开始内存里没有任何页面,接下来用户会请求Q个页面,你需要设计一个置换算法,使得缺页发生的次数最少。缺页是指用户请求某个编号的页面,但这个页面没有在内存中的情况。发生缺页之后,你必须要把硬盘内对应的页面调入内存中,如果内存已满,你需要置换掉当前内存中的某个页面。

输入描述:

多组数据,请处理到输入结束。
每组数据,第一行为三个整数N,M,Q (0 < N,M,Q <= 50000)
接下来一行Q个数,表示用户请求的页面编号。

输出描述:

对于每组数据,输出一个数,表示最少的缺页次数。




手写最佳页面置换算法23333。拿一个堆去维护当前最晚出现结点的值,并对每个页面在堆中的点的位置记录。然后去维护这个堆,每次缺页删去根节点。

  1 #include<bits/stdc++.h>
  2 #define clr(x) memset(x,0,sizeof(x))
  3 #define LL long long
  4 #define INF 0x3f3f3f3f
  5 using namespace std;
  6 const int N=1e5+10;
  7 int n,m,q,t,ans;
  8 int nexted[N],pre[N],hashed[N];
  9 int que[N];
 10 struct node{
 11     int len,num;
 12 }heap[N<<2];
 13 int tot,all;
 14 int add(int n,int len)
 15 {
 16     if(len<0) len=INF;
 17     heap[++tot]=(node){len,n};
 18     int p=tot;
 19     while(p>1 && heap[p].len>heap[p>>1].len)
 20     {
 21         swap(heap[p],heap[p>>1]);
 22         p>>=1;
 23     }
 24     return p;
 25 }
 26 int change(int has,int len)
 27 {
 28     if(len<0) len=INF;
 29     int p=has;
 30     heap[p].len=len;
 31     while(p>1 && heap[p].len>heap[p>>1].len)
 32     {
 33         swap(heap[p],heap[p>>1]);
 34         p>>=1;
 35     }
 36     int maxn;
 37     while(heap[p].len<heap[p<<1].len || heap[p].len<heap[p<<1|1].len)
 38     {
 39         maxn=heap[p<<1|1].len>heap[p<<1].len?(p<<1|1):(p<<1);
 40         swap(heap[p],heap[maxn]);
 41         p=maxn;
 42     }
 43     return p;
 44 }
 45 int pop()
 46 {
 47     int rt=heap[1].num;
 48     heap[1]=heap[tot];
 49     tot--;
 50     int p=1;
 51     int maxn;
 52     while(heap[p].len<heap[p<<1].len || heap[p].len<heap[p<<1|1].len)
 53     {
 54         maxn=heap[p<<1|1].len>heap[p<<1].len?(p<<1|1):(p<<1);
 55         swap(heap[p],heap[maxn]);
 56         p=maxn;
 57     }
 58     return rt;
 59 }
 60 int main()
 61 {
 62     while(scanf("%d%d%d",&n,&m,&q)!=EOF)
 63     {
 64         clr(pre);
 65         clr(hashed);
 66         clr(heap);
 67         tot=0;
 68         all=0;
 69         ans=0;
 70         for(int i=1;i<=q;i++)
 71         {
 72             scanf("%d",que+i);
 73             nexted[i]=-1;
 74             if(pre[que[i]])
 75                 nexted[pre[que[i]]]=i;
 76             pre[que[i]]=i;
 77         }
 78         for(int i=1;i<=q;i++)
 79         {
 80             if(all<n)
 81             {
 82                 if(!hashed[que[i]])
 83                 {
 84                     hashed[que[i]]=add(que[i],nexted[i]);
 85                     all++;
 86                 }
 87                 else
 88                 {
 89                     hashed[que[i]]=change(hashed[que[i]],nexted[i]);
 90                 }
 91             }
 92             else if(hashed[que[i]])
 93                 hashed[que[i]]=change(hashed[que[i]],nexted[i]);
 94             else
 95             {
 96                 t=pop();
 97                 hashed[t]=0;
 98                 hashed[que[i]]=add(que[i],nexted[i]);
 99                 ans++;
100             }
101 
102         }
103         printf("%d\n",ans+all);
104     }
105     return 0;
106 }
View Code

 

题目描述

众所周知,汀老师是XDUACM实验室最优秀的人,无论是学习还是打游戏。今天他突然想到一个好玩的游戏。规则是这样的,在游戏中他要得到n个小国,初始的时候小国和小杰各有1个。经过了很久的修炼,汀老师学会了两种魔法,他每次可以动用自己的智慧来使用魔法。

第一个魔法:(小杰变小国)可以将自己的智慧复制和当前小杰一样数量的小国出来;

第二个魔法:(小国大爆发)可以将当前的小杰变成和小国的数量一样,然后小国的数量加倍!

因为汀老师的智力是无限多的,他不关心花掉的智力大小。但是好学的汀老师想尽快得到n个小国,使得能有更多的时间去读paper和打比赛。他想问问你,最少需要使用多少次魔法可以得到n个小国。

得到了n个小国后,汀老师去学习,但是小国们基因突变在电脑里越来越多!他们来组织汀老师学习,现在告诉汀老师我要得到更多的同伴!

输入描述:

多组数据,第一行一个正整数T(T<=100000)表示数据组数。
接下来T行,每行一个正整数n(n<=10^6)。

输出描述:

对于每组数据输出一个整数,表示得到n个小国汀老师最少需要使用多少次膜法。
示例1

输入

2
1
3

输出

0
2



贼生气。。没说刚好要n个。。让我找了好久错没想到是要刚好n个。
你在纸上写几个结果看看。你可以发现如果一个数t是另一个数t*p的质数p倍的话,那么它的答案为(p-1)倍。那我们可以想到最优策略,先把原来的数t翻倍,然后+(p-2)次t。这样就p倍了。因此我们把p拆成质数连乘,然后答案就是每个质数(p-1)的和。我们可以通过线性筛快速求100w个。

 1 #include<bits/stdc++.h>
 2 #define clr(x) memset(x,0,sizeof(x))
 3 using namespace std;
 4 const int N=1e6+10;
 5 int inf[N];
 6 int eu[N];
 7 int prime[N];
 8 int tot;
 9 void  done(int n)
10 {
11     clr(prime);
12     clr(inf);
13     tot=0;
14     for(int i=2;i<=n;i++)
15     {
16         if(!inf[i])
17         {
18             prime[tot++]=i;
19             inf[i]=1;
20             eu[i]=i-1;
21         }
22         for(int j=0;j<tot;j++)
23         {
24             if(prime[j]>n/i) break;
25             inf[i*prime[j]]=1;
26             if(i%prime[j]==0)
27             {
28                 eu[i*prime[j]]=eu[i]+(prime[j]-1);
29                 break;
30             }
31             else
32                 eu[i*prime[j]]=eu[i]+(prime[j]-1);
33         }
34     }
35     return ;
36 }
37 int main()
38 {
39     int n,m;
40     done((int)1e6);
41     scanf("%d",&n);
42     for(int i=1;i<=n;i++)
43     {
44        scanf("%d",&m);
45         printf("%d\n",eu[m]);
46     }
47     return 0;
48 }
View Code

 

题目描述

Tr0y创办了一家安全公司,主要提供抗DDoS服务。
假设有n家公司共用Tr0y的第三方服务器,各公司初始最大承受带宽为xi Gbps,当其受到大于或等于最大承受带宽流量时,会判断为DDoS攻击并进行清洗操作,将流量引到第三方服务器。
下面有Q次攻击,每次使得[Li,Ri]的公司遭受到流量为c Gbps(c为整数,在[1,C]上离散均匀分布)的攻击,且每家公司在承受攻击后会增大qi Gbps的最大承受带宽。
Tr0y的资金有限,他想知道每次攻击时,他的服务器期望承受流量为多少?
答案应该会很大,请膜1e9+7。

输入描述:

第一行为三个整数n(1<=n<=1e5),C(1e7<=C<=1e9),Q(1<=n<=1e5)。
第二行含n个整数xi(1<=xi<=10)。
接下来Q行,每行包含三个整数L,R(1<=L<=R<=n),q(1<=q<=10).

输出描述:

共Q行,每行输出服务器期望承受流量.
示例1

输入

3 10000000 3
1 2 3
1 1 1
1 2 1
1 3 1

输出

505000004
581428605
86428702


这题每次操作相互独立。因此我们算每次操作的期望就好了。
划重点,注意数据范围!你会发觉Xi+ΣQj永远小于C,这点至关重要。

假如我们当前处理的公司流量为a1~ai,我们对每个c值,他被选中的概率是1/C。对于每个$a_i$能引流的是大于等于$a_i$那部分的c值,引流量为c。因此我们的答案就是

$ \sum^r_{i=l}  \ \frac{\sum^{C}_{t=a_i} \ t}{C} $ 

我们把这个式子拆开,我们会发现式子变成了

$\frac{(r-l+1)(c^2+c)+\sum^{r}_{i=l} \ a_i-\sum^{r}_{i=l} \ a_i^2}{2C} $

 那么我们要维护的东西就显而易见了,一个是区间和,一个是区间平方和。

因此我们建立线段树维护这两个值,然后求2C的逆元,就可以在每次读入一个$q_i$后logn直接得出答案,并logn更新区间。

  1 #include<bits/stdc++.h>
  2 #define clr(x) memset(x,0,sizeof(x))
  3 #define LL long long
  4 #define INF 0x3f3f3f3f
  5 #define mod 1000000007
  6 using namespace std;
  7 const int N=1e5+10;
  8 int n,q,l,r,qi;
  9 int x[N];
 10 LL c,t;
 11 struct node{
 12     int l,r;
 13     LL sum,pfsum,tag;
 14 }tree[N<<2];
 15 void pushdown(int i)
 16 {
 17     if(tree[i].tag)
 18     {
 19         if(tree[i].l!=tree[i].r)
 20         {
 21             tree[i<<1].tag=(tree[i<<1].tag+tree[i].tag)%mod;
 22             tree[i<<1].pfsum=(tree[i<<1].pfsum+2*tree[i<<1].sum%mod*tree[i].tag%mod+(tree[i<<1].r-tree[i<<1].l+1)*tree[i].tag%mod*tree[i].tag%mod)%mod;
 23             tree[i<<1].sum=(tree[i<<1].sum+tree[i].tag*(tree[i<<1].r-tree[i<<1].l+1)%mod)%mod;
 24             tree[i<<1|1].tag=(tree[i<<1|1].tag+tree[i].tag)%mod;
 25             tree[i<<1|1].pfsum=(tree[i<<1|1].pfsum+2*tree[i<<1|1].sum%mod*tree[i].tag%mod+(tree[i<<1|1].r-tree[i<<1|1].l+1)*tree[i].tag%mod*tree[i].tag%mod)%mod;
 26             tree[i<<1|1].sum=(tree[i<<1|1].sum+tree[i].tag*(tree[i<<1|1].r-tree[i<<1|1].l+1)%mod)%mod;        }
 27         tree[i].tag=0;
 28     }
 29     return ;
 30 }
 31 void pushup(int i)
 32 {
 33     tree[i].sum=(tree[i<<1].sum+tree[i<<1|1].sum)%mod;
 34     tree[i].pfsum=(tree[i<<1].pfsum+tree[i<<1|1].pfsum)%mod;
 35     return ;
 36 }
 37 void init(int i,int l,int r)
 38 {
 39     tree[i]=(node){l,r};
 40     if(l==r)
 41     {
 42         tree[i].sum=x[l];
 43         tree[i].pfsum=((LL)x[l]*x[l])%mod;
 44         return;
 45     }
 46     int mid=(l+r)>>1;
 47     init(i<<1,l,mid);
 48     init(i<<1|1,mid+1,r);
 49     pushup(i);
 50     return ;
 51 }
 52 void update(int i,int l,int r,int val)
 53 {
 54     if(tree[i].l>=l && tree[i].r<=r)
 55     {
 56         tree[i].tag=(tree[i].tag+val)%mod;
 57         tree[i].pfsum=(tree[i].pfsum+2*tree[i].sum%mod*val%mod+(tree[i].r-tree[i].l+1)*val%mod*val%mod)%mod;
 58         tree[i].sum=(tree[i].sum+val*(tree[i].r-tree[i].l+1)%mod)%mod;
 59         return ;
 60     }
 61     pushdown(i);
 62     int mid=(tree[i].l+tree[i].r)>>1;
 63     if(mid>=l)
 64         update(i<<1,l,r,val);
 65     if(mid<r)
 66         update(i<<1|1,l,r,val);
 67     pushup(i);
 68     return ;
 69 }
 70 LL query(int i,int l,int r)
 71 {
 72     if(tree[i].l>=l && tree[i].r<=r)
 73         return ((tree[i].sum-tree[i].pfsum)%mod+mod)%mod;
 74     pushdown(i);
 75     int mid=(tree[i].l+tree[i].r)>>1;
 76     if(mid<l)
 77         return query(i<<1|1,l,r);
 78     else if(mid>=r)
 79         return query(i<<1,l,r);
 80     else return (query(i<<1,l,r)+query(i<<1|1,l,r))%mod;
 81 }
 82 LL quickpow(LL x,LL n)
 83 {
 84     LL ans=1;
 85     x=x%mod;
 86     while(n)
 87     {
 88         if(n&1)
 89             ans=ans*x%mod;
 90         n>>=1;
 91         x=x*x%mod;
 92     }
 93     return ans;
 94 }
 95 LL ans,dc;
 96 int main()
 97 {
 98     scanf("%d%lld%d",&n,&c,&q);
 99     for(int i=1;i<=n;i++)
100         scanf("%d",x+i);
101     init(1,1,n);
102     dc=quickpow(2*c,mod-2);
103     for(int i=1;i<=q;i++)
104     {
105         scanf("%d%d%d",&l,&r,&qi);
106         printf("%lld\n",(query(1,l,r)+(r-l+1)*(c*c%mod+c)%mod)%mod*dc%mod);
107         update(1,l,r,qi);
108     }
109     return 0;
110 }
View Code

 

 

 

posted @ 2018-04-23 10:00  hk_lin  阅读(454)  评论(0编辑  收藏  举报