今天早上明明在看雅思的,结果看了10分钟又情不自禁的来想前天的B题来了。
这道题是PZR一发过的,PZR牛逼!!!
但是我今天想不通呀,拿着他的代码去问,这里是什么意思,那里又是什么意思。
问了一个多小时才搞懂,最先被自己蠢哭了,后来彭大佬被我问哭了。
题意大概是给一串数,然后每个数要和一个数异或,使得前一个数都小于后一个数,问这个数有多少种情况。
因为数据是2^60,要爆int的,用long long。
然后就把两个数都转化成二进制,从高位到低位比较,如果相同就继续往后,如果是0、1的情况那个数的位就是0,1、0的情况那个数的位就是1,也只有这两种情况那个数的位是确定的,所以我们都标记所有确定了的位置,不确定的位置用60相减,每一个不确定的位都存在0和1两种情况,所以就是2的n此幂。
Given a sequence a[1..n], you need to calculate how many integers S satisfy the following conditions:
(1). 0 ≤ S < 260
(2). For every i in [1,n-1] , (a[i] xor S) ≤ (a[i+1] xor S)
InputOn the first line there is only one integer n
On the second line there are n integers a[1..n]
1 ≤ n ≤ 50
0 ≤ a[i] < 260
OutputOutput one integer : the answer
Sample Input
3 1 2 3
Sample Output
288230376151711744
#include <cstdio> #include <iostream> #include <algorithm> #include <cmath> #include <set> #include <map> #include <queue> #include <cstring> using namespace std; int s[65]; void cmp(long long x,long long y){ int a[65]={0},b[65]={0}; int n=0,m=0; while(x>0){ a[n++]=x%2; x/=2; } while(y>0){ b[m++]=y%2; y/=2; } for(int i=59;i>=0;i--){ if(a[i]!=b[i]){ s[i]=1; break; } } return ; } int main() { unsigned long long num[55]; int n; int m=0; cin>>n; memset(s,0,sizeof(s)); for(int i=0;i<n;i++) cin>>num[i]; for(int i=0;i<n-1;i++) cmp(num[i],num[i+1]); for(int i=0;i<60;i++) if(s[i]==0) m++; long long sum=(long long)1<<m; cout<<sum<<endl; return 0; }
那天比赛前一天晚上本来身体就各种不舒服,又热,又有一大堆疯蚊子趁隙咬我,打都打不完,一晚上醒了六次,几乎没睡,第二天早上对着电脑直想吐。
中午胡乱吃了几口饭,只睡了20分钟,又起来比赛了,PZR又出去吃饭去了,我一来随缘就肝C,觉得用优先队列会很简单,但是上学期看的优先队列又忘得差不多了,结果就没弄出来。然后又换结构体数组做,rank标记,结果后来自己又被变量太多搞糊涂了。那个时候已经都有4个队过题了,我们一道都没整出来,我想吐,又憋着,做不出来。
然后我就悄悄咪咪的出去溜了个弯,经过然龟龟儿的时候,看他在肝G,整个电脑都是代码,写了估计有100多行吧,G题是给定八个坐标求长方形重叠面积占结合面积比率,因为我觉得我数学学的不好,然后我就先没过这个题。
后来PZR终于把饭吃完回来了,我也差不多遛弯回来了,还有一个队友一直在肝B却一直罚时,我就跟她说别过了,说不定过一会儿彭大佬回来我们就转运了。
我做的时候感觉G就像个脑筋急转弯,没有推任何公式,可能20多行就写出来了吧,可能是因为我聪明,嘿嘿。
然后我的G和彭大佬的B几乎同时过,好运来啊好运来~
当时C题还没人过,但是我个人感觉这道题不难,只是我优先队列怎么个写法忘得差不多了,我下来一定补补那块的知识。
然后我就想,那不用优先队列,队列也行啊,就是多几个判断条件嘛。
在彭大佬的提示下,加设了两个数组,一个是记录过题数的,另一个是记录罚时总和的,在计算1队的排名的时候,我们先依次吐出每一个队伍,如果那个队伍比1队优秀的那再吐回去就行了。
感觉代码实现没有想象的困难。还是彭大佬指引的好。
#include<iostream> #include<stdio.h> #include<string.h> #include<math.h> #include<algorithm> #include<queue> #include<set> using namespace std; queue <int> que; int main() { int n,m,x,a[100005]={0},str[100005]={0},vis[100005]={0},t,i; cin>>n>>m; while(m--) { cin>>x>>t; if(x!=1) { a[x]++; str[x]+=t; if((a[x]>a[1]||(a[x]==a[1]&&str[x]<str[1]))&&!vis[x]) { que.push(x); vis[x]=1; } cout<<que.size()+1<<endl; } else { a[1]++; str[1]+=t; int len=que.size(); for(i=1;i<=len;i++) { int p=que.front(); que.pop(); if(a[p]>a[1]||(a[p]==a[1]&&str[p]<str[1])) { que.push(p); } else vis[p]=0; } cout<<que.size()+1<<endl; } } return 0; }
后来彭大佬又把H过了。pzrNB!
再给大家分享两道练习赛的题:
第一道题就是找能由给出的所有2的幂组成所查找数的最小个数,如果都不能组成就输出-1。
奇数不一定输出-1,因为还有2的0次方是1。
要想个数最少,所以我们从最大的数开始遍历,应该不存在数列里有的大数不能组合但是比他小的数组合了的情况,因为那些大数是由小数构成的,剩下的项如果不能组合那就是不能组合了。
这道题也是超时超惨了,我现在对TLE都有免疫力了。
Polycarp has nn coins, the value of the ii-th coin is aiai. It is guaranteed that all the values are integer powers of 22 (i.e. ai=2dai=2d for some non-negative integer number dd).
Polycarp wants to know answers on qq queries. The jj-th query is described as integer number bjbj. The answer to the query is the minimum number of coins that is necessary to obtain the value bjbj using some subset of coins (Polycarp can use only coins he has). If Polycarp can't obtain the value bjbj, the answer to the jj-th query is -1.
The queries are independent (the answer on the query doesn't affect Polycarp's coins).
Input
The first line of the input contains two integers nn and qq (1≤n,q≤2⋅1051≤n,q≤2⋅105) — the number of coins and the number of queries.
The second line of the input contains nn integers a1,a2,…,ana1,a2,…,an — values of coins (1≤ai≤2⋅1091≤ai≤2⋅109). It is guaranteed that all aiai are integer powers of 22 (i.e. ai=2dai=2dfor some non-negative integer number dd).
The next qq lines contain one integer each. The jj-th line contains one integer bjbj — the value of the jj-th query (1≤bj≤1091≤bj≤109).
Output
Print qq integers ansjansj. The jj-th integer must be equal to the answer on the jj-th query. If Polycarp can't obtain the value bjbj the answer to the jj-th query is -1.
Example
5 4
2 4 8 2 4
8
5
14
10
1
-1
3
2
#include <stdio.h> #include <iostream> #include <algorithm> #include <string.h> #include<map> #define maxn 2000005 using namespace std; map<int,int>str; int main() { int n,q,a,x,i; scanf("%d%d",&n,&q); for(i=0; i<n; i++) { scanf("%d",&a); str[a]++; } while(q--) { scanf("%d",&x); int k=0; for(i=1<<30; i>=1; i/=2) { int t=min(x/i,str[i]); x-=t*i; k+=t; } if(x) printf("-1 "); else { printf("%d ",k); } } return 0; }
还有一道是求序列指定范围的最大平均数,我用暴力做结果第13 个样例超时了,后面改成前缀和就过了~啦啦
The heat during the last few days has been really intense. Scientists from all over the Berland study how the temperatures and weather change, and they claim that this summer is abnormally hot. But any scientific claim sounds a lot more reasonable if there are some numbers involved, so they have decided to actually calculate some value which would represent how high the temperatures are.
Mathematicians of Berland State University came up with a special heat intensity value. This value is calculated as follows:
Suppose we want to analyze the segment of nn consecutive days. We have measured the temperatures during these nn days; the temperature during ii-th day equals aiai.
We denote the average temperature of a segment of some consecutive days as the arithmetic mean of the temperature measures during this segment of days. So, if we want to analyze the average temperature from day xx to day yy, we calculate it as ∑i=xyaiy−x+1∑i=xyaiy−x+1 (note that division is performed without any rounding). The heat intensity value is the maximum of average temperatures over all segments of not less than kkconsecutive days. For example, if analyzing the measures [3,4,1,2][3,4,1,2] and k=3k=3, we are interested in segments [3,4,1][3,4,1], [4,1,2][4,1,2] and [3,4,1,2][3,4,1,2] (we want to find the maximum value of average temperature over these segments).
You have been hired by Berland State University to write a program that would compute the heat intensity value of a given period of days. Are you up to this task?
Input
The first line contains two integers nn and kk (1≤k≤n≤50001≤k≤n≤5000) — the number of days in the given period, and the minimum number of days in a segment we consider when calculating heat intensity value, respectively.
The second line contains nn integers a1a1, a2a2, ..., anan (1≤ai≤50001≤ai≤5000) — the temperature measures during given nn days.
Output
Print one real number — the heat intensity value, i. e., the maximum of average temperatures over all segments of not less than kk consecutive days.
Your answer will be considered correct if the following condition holds: |res−res0|<10−6|res−res0|<10−6, where resres is your answer, and res0res0 is the answer given by the jury's solution.
Example
4 3
3 4 1 2
2.666666666666667
#include <bits/stdc++.h> using namespace std; int main() { int n,k,a[5005]={0},i,j,str[5005]={0}; cin>>n>>k; for(i=1;i<=n;i++) { cin>>a[i]; str[i]=str[i-1]+a[i]; } double sum=0,maxx=0; for(i=k;i<=n;i++) { for(j=1;j+i-1<=n;j++) { sum=max(sum,(double)(str[i+j-1]-str[j-1])/i); } } printf("%.8f ",sum); }
上周说要挤时间学算法,结果晚上要么弄大创要么死盯着排名补题去了。
我们还是很厉害的,大一大二大三的所有队在一起比,结果我们排名第三,pzrnb!
我这一周补题要提高效率,然后剩下的时间要好好研究一下算法,因为我有一个非常非常非常NB的队友,我不要拖他的后腿。
做题还要提高自己的精准度,给自己罚时可以,绝不给大佬加罚时。
可怕加油!相信自己!
PZRNB!