2020.4.11--组队赛
作者:互联网
A - Wrestling Match
Nowadays, at least one wrestling match is held every year in our country. There are a lot of people in the game is "good player”, the rest is "bad player”. Now, Xiao Ming is referee of the wrestling match and he has a list of the matches in his hand. At the same time, he knows some people are good players,some are bad players. He believes that every game is a battle between the good and the bad player. Now he wants to know whether all the people can be divided into "good player" and "bad player".
InputInput contains multiple sets of data.For each set of data,there are four numbers in the first line:N (1 ≤ N≤ 1000)、M(1 ≤M ≤ 10000)、X,Y(X+Y≤N ),in order to show the number of players(numbered 1toN ),the number of matches,the number of known "good players" and the number of known "bad players".In the next M lines,Each line has two numbersa, b(a≠b) ,said there is a game between a and b .The next line has X different numbers.Each number is known as a "good player" number.The last line contains Y different numbers.Each number represents a known "bad player" number.Data guarantees there will not be a player number is a good player and also a bad player.OutputIf all the people can be divided into "good players" and "bad players”, output "YES", otherwise output "NO".Sample Input
5 4 0 0 1 3 1 4 3 5 4 5 5 4 1 0 1 3 1 4 3 5 4 5 2
Sample Output
NO YES
题意:有n个人每个人只能是好人或者是坏人,给你n对人的关系,每对的中两个人的关系是对立的,一定有一个 是坏人一个是好人,并且给了 x个确定是好人的编号, y个确定是坏人的编号,现在让你判断,是否能将 所有人划分成两个阵营(有人的身份不能确定也不行)
思路:裸的二分染色,按照输入情况进行建边,然后按照输入的x,y进行染色判断如果有矛盾那一定是不行的, 最后在讲给出的条件进行染色,最后如果有身份不明的人就可以除去了
#include <stdio.h> #include <vector> #include <string.h> #include <queue> #include <iostream> using namespace std; int n,m; int x,y; int a[10005],b[10005]; vector<int>edge[1005]; int vis[1005]; bool ok; int str; void bfs(int u,int flag){ queue<int>q; q.push(u); vis[u]=flag; while(!q.empty()){ int tmp=q.front(); q.pop(); for(int i=0;i<edge[tmp].size();i++){ int v=edge[tmp][i]; if(vis[v]==vis[tmp]){ ok=false; return; } if(vis[v]==0){ vis[v]=(-vis[tmp]); q.push(v); } } } } void init(){ ok=true; memset(vis,0,sizeof vis); for(int i=0;i<1005;i++){ edge[i].clear(); } } int main(){ // freopen("in.txt","r",stdin); while(scanf("%d%d%d%d",&n,&m,&x,&y)!=EOF){ init(); for(int i=0;i<m;i++){ scanf("%d%d",&a[i],&b[i]); edge[a[i]].push_back(b[i]); edge[b[i]].push_back(a[i]); } for(int i=0;i<x;i++){ scanf("%d",&str); if(vis[str]==-1){ ok=false; } bfs(str,1); } for(int i=0;i<y;i++){ scanf("%d",&str); if(vis[str]==1){ ok=false; } bfs(str,-1); } for(int i=0;i<m;i++){ if(vis[a[i]]==0&&vis[b[i]]==0) bfs(a[i],1); } for(int i=1;i<=n;i++){ if(vis[i]==0){ ok=false; break; } } printf(ok?"YES\n":"NO\n"); } return 0; }
B - Regular Number
Using regular expression to define a numeric string is a very common thing. Generally, use the shape as follows:
(0|9|7) (5|6) (2) (4|5)
Above regular expression matches 4 digits:The first is one of 0,9 and 7. The second is one of 5 and 6. The third is 2. And the fourth is one of 4 and 5. The above regular expression can be successfully matched to 0525, but it cannot be matched to 9634.
Now,giving you a regular expression like the above formula,and a long string of numbers,please find out all the substrings of this long string that can be matched to the regular expression.
InputIt contains a set of test data.The first line is a positive integer N (1 ≤ N ≤ 1000),on behalf of the regular representation of the N bit string.In the next N lines,the first integer of the i-th line is ai(1≤ai≤10)ai(1≤ai≤10),representing that the i-th position of regular expression has aiai numbers to be selected.Next there are aiai numeric characters. In the last line,there is a numeric string.The length of the string is not more than 5 * 10^6.OutputOutput all substrings that can be matched by the regular expression. Each substring occupies one lineSample Input
4 3 0 9 7 2 5 7 2 2 5 2 4 5 09755420524
Sample Output
9755 7554 0524思路:使用bitset<N> b[10] ,b[i][j]表示值为i的数可以出现在子串的那些位置,即下标,那么对主串进行遍历 i=0:len-1 。另外定义一个变量bitset<N> ans ,每次先将ans左移一位,然后将最低位置1,然后令k=当前输入的数,将ans=ans&b[k], 如果当前ans[N-1]==1,那么主串s[i-N+1]~s[i]就是合法子串,输出;
题意:输入N ,表示有一个长为N的子串,接下来N行,每行输入ai 和ai个数,表示有ai个数,表示子串第i个字符为ai个数中的一个,也就是这个子串的正则式,然后输入一个主串,要求输出这个主串中包含的所有的子串。
#include <iostream> #include <algorithm> #include <cstdio> #include <cstring> #include <bitset> using namespace std; typedef long long LL; const int M=5*1e6+5; bitset<1005>b[12]; bitset<1005>ans; char s[5000005]; int main() { int N; while(scanf("%d",&N)!=EOF) { for(int i=0;i<10;i++) b[i].reset(); for(int i=0;i<N;i++) { int n; scanf("%d",&n); for(int j=1;j<=n;j++) { int k; scanf("%d",&k); b[k].set(i); } } getchar(); gets(s); ans.reset(); int len=strlen(s); for(int i=0;i<len;i++) { ans=ans<<1; ans.set(0); ans=ans&b[s[i]-'0']; if(ans[N-1]==1){ char c=s[i+1]; s[i+1]='\0'; puts(s+i-N+1); s[i+1]=c; } } } return 0; }Two people face two piles of stones and make a game. They take turns to take stones. As game rules, there are two different methods of taking stones: One scheme is that you can take any number of stones in any one pile while the alternative is to take the same amount of stones at the same time in two piles. In the end, the first person taking all the stones is winner.Now,giving the initial number of two stones, can you win this game if you are the first to take stones and both sides have taken the best strategy?
InputInput contains multiple sets of test data.Each test data occupies one line,containing two non-negative integers a andb,representing the number of two stones.a and b are not more than 10^100.OutputFor each test data,output answer on one line.1 means you are the winner,otherwise output 0.Sample Input
2 1 8 4 4 7
Sample Output
0 1 0
题目大意:两个人抓石子,有两堆石子,石子数量分别是a,b,每次可以从一堆中抓若干石子,也可以从两堆同时抓取相同数量的石子,谁先抓完谁获胜,现在你先手,问是否必胜,必胜输出1否则输出0.
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Scanner;
public class Mainn {
public static void main(String[] args)
{
Scanner cin = new Scanner(System.in);
BigDecimal two,three,five,a,b;
two = BigDecimal.valueOf(2);
three = BigDecimal.valueOf(3);
five = BigDecimal.valueOf(5);
BigDecimal l = two,r = three;
for(int i=0;i<500;i++)
{
BigDecimal mid = l.add(r).divide(two);
if(mid.multiply(mid).compareTo(five)<0)
l = mid;
else r = mid;
}
BigDecimal g = l.add(BigDecimal.ONE).divide(two);
while(cin.hasNext())
{
a = cin.nextBigDecimal();
b = cin.nextBigDecimal();
if(a.compareTo(b)<0)
{
BigDecimal tmp = a;
a=b;
b=tmp;
}
BigDecimal tmp = a.subtract(b);
tmp = tmp.multiply(g);
tmp = tmp.setScale(0,BigDecimal.ROUND_FLOOR);
if(tmp.compareTo(b)==0)
System.out.println("0");
else System.out.println("1");
}
}
}
D - A Simple Math Problem
Given two positive integers a and b,find suitable X and Y to meet the conditions:
X+Y=a
Least Common Multiple (X, Y) =b
InputInput includes multiple sets of test data.Each test data occupies one line,including two positive integers a(1≤a≤2*10^4),b(1≤b≤10^9),and their meanings are shown in the description.Contains most of the 12W test cases.OutputFor each set of input data,output a line of two integers,representing X, Y.If you cannot find such X and Y,output one line of "No Solution"(without quotation).Sample Input
6 8 798 10780
Sample Output
No Solution 308 490
#include <cstdio> #include <algorithm> #include <cstring> #include <cmath> using namespace std; #define ll long long ll a,b,i,j,c,d; ll gcd(ll a,ll b){ return b?gcd(b,a%b):a; } int main(){ while (~scanf("%I64d%I64d",&a,&b)){ c=gcd(a,b); d=a*a-4*b*c; if (d<0){ puts("No Solution"); continue; } i=(a-sqrt(d))/2/c; j=(a+sqrt(d))/2/c; if (i*j*c==b) printf("%I64d %I64d\n",i*c,j*c); else puts("No Solution"); } return 0; }
E - Aninteresting game
Let’s play a game.We add numbers 1,2...n in increasing order from 1 and put them into some sets.
When we add i,we must create a new set, and put iinto it.And meanwhile we have to bring [i-lowbit(i)+1,i-1] from their original sets, and put them into the new set,too.When we put one integer into a set,it costs us one unit physical strength. But bringing integer from old set does not cost any physical strength.
After we add 1,2...n,we have q queries now.There are two different kinds of query:
1 L R:query the cost of strength after we add all of [L,R](1≤L≤R≤n)
2 x:query the units of strength we cost for putting x(1≤x≤n) into some sets.
InputThere are several cases,process till end of the input.
For each case,the first line contains two integers n and q.Then q lines follow.Each line contains one query.The form of query has been shown above.
n≤10^18,q≤10^5
OutputFor each query, please output one line containing your answer for this querySample Input
10 2 1 8 9 2 6
Sample Output
9 2
Hint
lowbit(i) =i&(-i).It means the size of the lowest nonzero bits in binary of i. For example, 610=1102, lowbit(6) =102= 210 When we add 8,we should bring [1,7] and 8 into new set. When we add 9,we should bring [9,8] (empty) and 9 into new set. So the first answer is 8+1=9. When we add 6 and 8,we should put 6 into new sets. So the second answer is 2.
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <queue> #include <stack> #include <map> #include <set> #include <vector> #include <iomanip> #define ALL(x) (x).begin(), (x).end() #define rt return #define dll(x) scanf("%I64d",&x) #define xll(x) printf("%I64d\n",x) #define sz(a) int(a.size()) #define all(a) a.begin(), a.end() #define rep(i,x,n) for(int i=x;i<n;i++) #define repd(i,x,n) for(int i=x;i<=n;i++) #define pii pair<int,int> #define pll pair<long long ,long long> #define gbtb ios::sync_with_stdio(false),cin.tie(0),cout.tie(0) #define MS0(X) memset((X), 0, sizeof((X))) #define MSC0(X) memset((X), '\0', sizeof((X))) #define pb push_back #define mp make_pair #define fi first #define se second #define eps 1e-6 #define gg(x) getInt(&x) #define db(x) cout<<"== [ "<<x<<" ] =="<<endl; using namespace std; typedef long long ll; ll gcd(ll a,ll b){return b?gcd(b,a%b):a;} ll lcm(ll a,ll b){return a/gcd(a,b)*b;} ll powmod(ll a,ll b,ll MOD){ll ans=1;while(b){if(b%2)ans=ans*a%MOD;a=a*a%MOD;b/=2;}return ans;} inline void getInt(int* p); const int maxn=1000010; const int inf=0x3f3f3f3f; /*** TEMPLATE CODE * * STARTS HERE ***/ ll solve(ll x) { ll res=0ll; for(ll p=1ll;p<=x;p<<=1) { res+=(x/p-x/(p<<1))*p; } return res; } ll lowbit(ll x) { return x&(-x); } ll solve2(ll x,ll n) { ll res=0ll; while(x<=n) { res++; x+=lowbit(x); } return res; } int main() { ll n,q; while(~scanf("%lld %lld",&n,&q)) { int op; while(q--) { scanf("%d",&op); if(op==1) { ll l,r; scanf("%lld %lld",&l,&r); ll res=solve(r)-solve(l-1ll); printf("%lld\n",res ); }else { ll x; scanf("%lld",&x); printf("%lld\n",solve2(x,n) ); } } } return 0; } inline void getInt(int* p) { char ch; do { ch = getchar(); } while (ch == ' ' || ch == '\n'); if (ch == '-') { *p = -(getchar() - '0'); while ((ch = getchar()) >= '0' && ch <= '9') { *p = *p * 10 - ch + '0'; } } else { *p = ch - '0'; while ((ch = getchar()) >= '0' && ch <= '9') { *p = *p * 10 + ch - '0'; } } }
F - Detachment
In a highly developed alien society, the habitats are almost infinite dimensional space.
In the history of this planet,there is an old puzzle.
You have a line segment with x units’ length representing one dimension.The line segment can be split into a number of small line segments: a1,a2a1,a2, … (x= a1+a2a1+a2+…) assigned to different dimensions. And then, the multidimensional space has been established. Now there are two requirements for this space:
1.Two different small line segments cannot be equal ( ai≠ajai≠aj when i≠j).
2.Make this multidimensional space size s as large as possible (s= a1∗a2a1∗a2*...).Note that it allows to keep one dimension.That's to say, the number of ai can be only one.
Now can you solve this question and find the maximum size of the space?(For the final number is too large,your answer will be modulo 10^9+7)
InputThe first line is an integer T,meaning the number of test cases.
Then T lines follow. Each line contains one integer x.
1≤T≤10^6, 1≤x≤10^9OutputMaximum s you can get modulo 10^9+7. Note that we wants to be greatest product before modulo 10^9+7.Sample Input
1 4
Sample Output
4
题意:把一个数拆成若干个不相同的数之和,问这些数的乘积最大是多少。
思路:一般要使乘积最大,那么先拆成两个不同数时,这两个数一定是接近n/2,然后每一个数又可以拆成两个数。但要这些数都不相同,所以最好的情况肯定是n等于从2开始一直到某个数k的连续和,如9=2+3+4,这样肯定是最优的,那么n-sum(2+...+k)怎么处理呢?如11=2+3+4+2,还剩了个2,那么只能把这个数分配给它们其中的一个,首先,肯定是分给越小的数越好,这样提升乘积更大,而且还不能重复,就只能给(k+1)-多出来的数,11的话就是给到3,这里要二分来找,最后的答案就是2到k的乘积除以给到的数再乘以给到的数加多出来的数,这里除以要用到逆元,乘积和sum都可以前缀和预处理出来。
#include <bits/stdc++.h> #define INF 0x3f3f3f3f #define eps 1e-7 #define fuck(x) cout<<"<"<<x<<">"<<endl #define fi first #define se second #define pb push_back #define lson l, m, rt<<1 #define rson m+1, r, rt<<1|1 using namespace std; typedef long long LL; typedef unsigned long long ull; typedef pair<int, int> pii; const double PI = acos(-1.0); const LL INFLL = 0x3f3f3f3f3f3f3f3fll; const int maxn = 1e5 + 5; const int mod = 1e9 + 7; int t,n; LL sum[maxn]; LL ji[maxn]; int num[maxn],cnt; LL qp(LL a,LL b){ LL ans=1; while (b){ if (b&1) ans=(ans*a)%mod; a=(a*a)%mod; b>>=1; } return ans; } int main() { sum[0]=sum[1]=0; ji[0]=ji[1]=1; cnt=0; for (int i=2;i<=maxn;i++){ num[cnt++]=i; sum[i]=sum[i-1]+i; ji[i]=ji[i-1]*i%mod; if (sum[i]>1e9) break; } scanf ("%d",&t); while (t--){ scanf ("%d",&n); if (n==1) {printf ("1\n");continue;} int i=upper_bound(sum,sum+cnt+2,n)-sum; i--; int tmp=n-sum[i]; int pos=lower_bound(num,num+cnt,i+1-tmp)-num; LL x=(LL)num[pos]; LL ans=(ji[i]%mod*qp(x,mod-2)%mod)%mod; ans=ans*(x+tmp)%mod; printf ("%lld\n",ans); } return 0; }
G - Garden of Eden
When God made the first man, he put him on a beautiful garden, the Garden of Eden. Here Adam lived with all animals. God gave Adam eternal life. But Adam was lonely in the garden, so God made Eve. When Adam was asleep one night, God took a rib from him and made Eve beside him. God said to them, “here in the Garden, you can do everything, but you cannot eat apples from the tree of knowledge.”One day, Satan came to the garden. He changed into a snake and went to live in the tree of knowledge. When Eve came near the tree someday, the snake called her. He gave her an apple and persuaded her to eat it. Eve took a bite, and then she took the apple to Adam. And Adam ate it, too. Finally, they were driven out by God and began a hard journey of life.
The above is the story we are familiar with. But we imagine that Satan love knowledge more than doing bad things. In Garden of Eden, the tree of knowledge has n apples, and there are k varieties of apples on the tree. Satan wants to eat all kinds of apple to gets all kinds of knowledge.So he chooses a starting point in the tree,and starts walking along the edges of tree,and finally stops at a point in the tree(starting point and end point may be same).The same point can only be passed once.He wants to know how many different kinds of schemes he can choose to eat all kinds of apple. Two schemes are different when their starting points are different or ending points are different.
InputThere are several cases.Process till end of input.
For each case, the first line contains two integers n and k, denoting the number of apples on the tree and number of kinds of apple on the tree respectively.
The second line contains n integers meaning the type of the i-th apple. Types are represented by integers between 1 and k .
Each of the following n-1 lines contains two integers u and v,meaning there is one edge between u and v.1≤n≤50000, 1≤k≤10
OutputFor each case output your answer on a single line.Sample Input
3 2 1 2 2 1 2 1 3
Sample Output
6
题意:给一棵节点数为n,节点种类为k的无根树,问其中有多少种不同的简单路径,可以满足路径上经过所有k种类型的点?(a->b与b->a算作两条路径,起点与终点也可以相同)
#include<bits/stdc++.h> using namespace std; #define maxn 100100 #define maxm 200005 #define rd(x) scanf("%d", &x) #define rd2(x, y) scanf("%d%d", &x, &y) #define mod 1000000007 int V[maxn]; struct Edge{ int next,v; }edge[maxn*4]; int head[maxn],vis[maxn], tot; int n,k; long long int res; int f[15], sz[maxn], mx[maxn]; void addedge(int u, int v){ edge[tot].v = v; edge[tot].next = head[u]; head[u] = tot++; } map<int, long long int> mp[maxn]; void init(){ tot = 0; memset(head, -1, sizeof(head)); memset(vis, 0, sizeof(vis)); for(int i = 0; i < 10; i++){ f[i+1] = 1 << i; } for(int i = 1; i <= n ; i++){ mp[i].clear(); } } ///统计子树大小 void dfsize(int x, int fa){ sz[x] = 1; mx[x] = 0; for(int i = head[x]; i != -1; i = edge[i].next){ int v = edge[i].v; if(v == fa || vis[v]) continue; dfsize(v, x); sz[x] += sz[v]; if(sz[v] > mx[v]) mx[x] = sz[v]; } } void dfsroot(int r, int x, int fa, int &root, int &mm){ if(sz[r] - sz[x] > mx[x]) mx[x] = sz[r] - sz[x]; if(mx[x] < mm) mm = mx[x], root = x; for(int i = head[x]; i != -1; i = edge[i].next){ int v = edge[i].v; if(v == fa || vis[v]) continue; dfsroot(r, v, x, root, mm); } } vector<long long int> vec; void cal(int x, int fa, int kk, int root){ // 计算当前子树中合法的点对数 int fx = f[V[x]]; kk = (kk | fx); int k2 = (1 << k) -1 - kk; int ks = (1 << k) -1; if(x != root) { for(map<int, long long int>::iterator it = mp[root].begin(); it != mp[root].end(); it++){ int k3 = (*it).first; if((k3 & k2) == k2) res += (*it).second; } vec.push_back(kk); } for(int i = head[x]; i != -1; i = edge[i].next){ int v = edge[i].v; if(v == fa || vis[v]) continue; cal(v, x, kk, root); if(x == root){ int k2 = (1 << k) -1; for(int i =0 ; i < vec.size(); i++){ mp[root][vec[i]]++; //if(vec[i] == k2) res++; } vec.clear(); } } } void solve(int x){ dfsize(x, x); int mm = n + 1; int root; dfsroot(x, x, x, root, mm); vec.clear(); mp[root][0]++; cal(root, root, 0, root); vis[root] = 1; for(int i = head[root]; i != -1; i = edge[i].next){ int v = edge[i].v; if(vis[v]) continue; solve(v); } } int main() { int a, b; while(~scanf("%d%d", &n, &k)){ for(int i =1; i <= n; i++){ rd(V[i]); } init(); res = 0; for(int i =1; i < n; i++){ rd2(a, b); addedge(a, b); addedge(b, a); } if(k == 1){ printf("%lld\n", 1LL*n*n); continue; } solve(1); res = res*2; if(k == 1) res += n; printf("%lld\n", res); } return 0; }
H - To begin or not to begin
A box contains black balls and a single red ball. Alice and Bob draw balls from this box without replacement, alternating after each draws until the red ball is drawn. The game is won by the player who happens to draw the single red ball. Bob is a gentleman and offers Alice the choice of whether she wants to start or not. Alice has a hunch that she might be better off if she starts; after all, she might succeed in the first draw. On the other hand, if her first draw yields a black ball, then Bob’s chances to draw the red ball in his first draw are increased, because then one black ball is already removed from the box. How should Alice decide in order to maximize her probability of winning? Help Alice with decision.
InputMultiple test cases (number of test cases≤50), process till end of input.
For each case, a positive integer k (1≤k≤10^5) is given on a single line.
OutputFor each case, output:
1, if the player who starts drawing has an advantage
2, if the player who starts drawing has a disadvantage
0, if Alice's and Bob's chances are equal, no matter who starts drawing
on a single line.
Sample Input
1 2
Sample Output
0 1
#include<stdio.h> int main() { int k; while(~scanf("%d",&k)) { if(k%2==0)printf("1\n"); else if(k%2!=0)printf("0\n"); else printf("2\n"); } }
I - Convex
We have a special convex that all points have the same distance to origin point.
As you know we can get N segments after linking the origin point and the points on the convex. We can also get N angles between each pair of the neighbor segments.
Now give you the data about the angle, please calculate the area of the convex
InputThere are multiple test cases.
The first line contains two integer N and D indicating the number of the points and their distance to origin. (3 <= N <= 10, 1 <= D <= 10)
The next lines contain N integers indicating the angles. The sum of the N numbers is always 360.
OutputFor each test case output one float numbers indicating the area of the convex. The printed values should have 3 digits after the decimal point.
Sample Input
4 1 90 90 90 90 6 1 60 60 60 60 60 60
Sample Output
2.000 2.598
#include<stdio.h> #include<math.h> #define PI 3.1415926 int main() { int n,m,i,t; while(scanf("%d%d",&n,&m)!=EOF){ double sum=0; for(i=0;i<n;i++) { scanf("%d",&t); sum+=0.5*m*m*sin(t/180.0*PI); } printf("%.3lf\n",sum); } }
J - Find Small A
As is known to all,the ASCII of character 'a' is 97. Now,find out how many character 'a' in a group of given numbers. Please note that the numbers here are given by 32 bits’ integers in the computer.That means,1digit represents 4 characters(one character is represented by 8 bits’ binary digits).
InputThe input contains a set of test data.The first number is one positive integer N (1≤N≤100),and then N positive integersai (1≤ aiai≤2^32 - 1) followOutputOutput one line,including an integer representing the number of 'a' in the group of given numbers.Sample Input
3 97 24929 100
Sample Output
3
题意:给N个数 每个数都可以拆开成一个32位的2进制 每八位一个字节 每个字节的2进制数换算成十进制的看有多少个97
思路:CillyB: % 256是看看后8位是多少, /= 256是去掉后8位,仔细想想 % 2^8其实就是后面8位的值(这一点记住吧) /= 就是 >> 8位
#include<iostream> #include<cstdio> #include<cstring> using namespace std; int main(void) { int n; while(cin >> n) { int ans = 0, t; for(int i = 0; i < n; i++) { scanf("%d", &t); while(t) { if(t%256 == 97) ans++; t /= 256; } } printf("%d\n", ans); } return 0; }
K - Guess the number
AOA just met a problem when he attended an interview, as shown below:
A and B two people play guessing games. A thinks of a number x between a and b randomly in his mind, and he lets B to guess this number. A will say too small if B’s guess is less than x and A will say yes if B’s guess is just x.Once B’sguess is bigger than x,A won't speak any more.After that,A just nods his head if B’s guess is just x,otherwise shakes his head.The problem is that how many kinds of best guess strategies to make the least number of guesses in the worst situation?
InputInput contains multiple sets of test data and each of them occupies one line,including two integersa, b(1≤a≤b≤5 * 10^6),on behalf of range of the number.Input to the end of the file.OutputFor each set of input, output one line containing two integers. The first one represents the least number of times of guessing in the worst situation. The second one represents the number of best guess method modulo 100000073.Sample Input
1 5
Sample Output
3 3
Hint
B can guess the number in A's mind up to 3 times in the worst case. The first method,B can guess in the order of (2,4,5) The second method,B can guess in the order of (3,4,5) The third method,B can guess in the order of (3,5) Each method is up to three times.
题意:A和B玩一个游戏:A在[L,R]之间随机选取一个数X,之后由B来猜这个数,如果猜的数比X小,则A就告诉B你猜的数小了,如果猜的数等于X则游戏结束,如果猜的数大于X,则在这之后A只会回答B是否猜对了,而不会告诉B是否猜小了。问:在最坏的情况下,B猜到X时最少需要猜多少次,并输出方案数
题解:这道题其实有一道一模一样的题目:有n层楼,2颗鸡蛋,鸡蛋有个强度:可以在第X层楼摔下去且不会碎,要求用这2颗鸡蛋测试X是哪一层楼。
假设需要k次测试就能测完,那么我们该如何进行测试呢?因为第一颗蛋碎了,第二颗就只能一层一层地往上试。因此第一次测试时,就应该选择第k层进行测试,如果在第k层碎了,则从第1层开始遍历到第k-1层,一共需要k次;如果在第k层没有碎,那么还剩k-1次,我们就选择在k+k-1层进行测试,然后一直进行下去。
计算下来,进行k次测试,最高可以测试的层数为:k+(k-1)+...+1=k(k+1)/2
#include<bits/stdc++.h> using namespace std; typedef long long LL; const int MX = 5e6 + 5; const int mod = 100000073; int f[MX], p[MX], cnt[MX], sum[MX]; int main() { for (int x = 0, index = 1; index < MX;) { if (x * (x + 1) / 2 < index) p[++x] = index; f[index++] = x; } cnt[1] = 1, cnt[2] = 2; sum[1] = 1, sum[2] = 3; for (int i = 3; i < MX; i++) { int st = i - f[i], ed = p[f[i]] - 1; cnt[i] = (sum[ed] - sum[st - 1] + mod) % mod; sum[i] = (sum[i - 1] + cnt[i]) % mod; } int L, R; while (~scanf ("%d%d", &L, &R) ) printf ("%d %d\n", f[R - L + 1], cnt[R - L + 1]); return 0; }
标签:11,组队,2020.4,number,two,int,line,include,define 来源: https://www.cnblogs.com/mxw000120/p/12722568.html