A - Olympic Ranking 题意 :n支队伍,各有一定数量的金牌,银牌,铜牌。按照金牌 > 银牌 > 铜牌的优先级,找出最强的队伍。
题解 :题意简单,难点在于输入那个字符串。<1> 使用 getline和 string配合,然后输出的时候从第 1位输出而不是第 0位,会 wa12。<2> 我是手写了一个输入字符串的函数。<3> 我队友用的 map + tuple + string,也把代码附上,可以做个参考。(%%%
代码 :**<2>**
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 #include <bits/stdc++.h> using namespace std;#define endl "\n" #define ll long long #define inf 0x3f3f3f3f #define infll 1e15+7 #define IOS ios::sync_with_stdio(0); cin.tie(0) #define debug(a) cout<<"*****\tdebug: " <<a<<"\t*****" <<endl; const double eps = 1e-7 ;const double pi = acos (-1.0 );const int mod = 1e9 +7 ;const int N = 5 + 1e3 ;void getstr (char s[], int Lim) { int i = 0 ; char ch = getchar (); while (ch == ' ' ) ch = getchar (); while (ch != '\n' && ch != EOF && i < Lim) { s[i++] = ch; ch = getchar (); } s[i] = 0 ; } int a[N], b[N], c[N];char s[310 ][100000 ];int main () {#ifndef ONLINE_JUDGE freopen ("in.in" , "r" , stdin); freopen ("out.out" , "w" , stdout); #endif int n; cin>>n; for (int i = 1 ; i <= n; i++) { cin>>a[i]>>b[i]>>c[i]; getstr (s[i], 100000 ); } int ans = 1 ; for (int i = 2 ; i <= n; i++) if ((a[i] > a[ans]) || (a[i] == a[ans] && b[i] > b[ans]) || (a[i] == a[ans] && b[i] == b[ans] && c[i] > c[ans])) ans = i; printf ("%s" , s[ans]); return 0 ; }
代码:<3>
B - Aliquot Sum 题意 :求一个数的因子之和(除了自己本身),然后和自身比大小,对应输出三种字符串。
题解 :预处理一下即可。
代码 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 #include <bits/stdc++.h> using namespace std;#define endl "\n" #define ll long long #define inf 0x3f3f3f3f #define infll 1e15+7 #define IOS ios::sync_with_stdio(0); cin.tie(0) #define debug(a) cout<<"*****\tdebug: " <<a<<"\t*****" <<endl; const double eps = 1e-7 ;const double pi = acos (-1.0 );const int mod = 1e9 +7 ;const int N = 5 + 1e6 ;ll ans[N]; int main () {#ifndef ONLINE_JUDGE freopen ("in.in" , "r" , stdin); freopen ("out.out" , "w" , stdout); #endif for (int i = 1 ; i < 1000010 ; i++) for (int j = 2 *i; j < 1000010 ; j += i) ans[j] += i; int T; cin>>T; while (T--) { int x; cin>>x; if (ans[x] > x) cout<<"abundant" <<endl; else if (ans[x] == x) cout<<"perfect" <<endl; else cout<<"deficient" <<endl; } return 0 ; }
C - A Sorting Problem 题意 :给定一个数组,求逆序对数。
题解 :板子题,树状数组跑一遍即可。
代码 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 #include <bits/stdc++.h> using namespace std;#define endl "\n" #define ll long long #define inf 0x3f3f3f3f #define infll 1e15+7 #define IOS ios::sync_with_stdio(0); cin.tie(0) #define debug(a) cout<<"*****\tdebug: " <<a<<"\t*****" <<endl; const double eps = 1e-7 ;const double pi = acos (-1.0 );const int mod = 1e9 +7 ;const int N = 5 + 1e6 ;int n;int tree[N], f[N];struct node { int x, idx; }a[N]; bool cmp (node a, node b) { return a.x < b.x; } int lowbit (int i) { return i & -i; } void update (int pos, int val) { for (int i = pos; i <= n; i += lowbit (i)) tree[i] += val; } int ask (int pos) { int res = 0 ; for (int i = pos; i > 0 ; i -= lowbit (i)) res += tree[i]; return res; } int main () {#ifndef ONLINE_JUDGE freopen ("in.in" , "r" , stdin); freopen ("out.out" , "w" , stdout); #endif IOS; cin>>n; for (int i = 1 ; i <= n; i++) { cin>>a[i].x; a[i].idx = i; } sort (a+1 , a+n+1 , cmp); f[a[1 ].idx] = 1 ; for (int i = 2 ; i <= n; i++) { if (a[i].x != a[i-1 ].x) f[a[i].idx] = i; else f[a[i].idx] = f[a[i-1 ].idx]; } ll ans = 0 ; for (int i = 1 ; i <= n; i++) { update (f[i], 1 ); ans += i - ask (f[i]); } cout<<ans<<endl; return 0 ; }
D - Drunk Passenger 题意 :n个人按照先后顺序上飞机坐座位,第一个人喝醉了,所以他会等可能地坐到除了自己位置之外的位置上。剩下的乘客,如果自己的位置被占了,就会等可能的坐到其他位置上,否则坐自己的位置。求最后一个人做对位置的概率。
题解 :【醉汉、1、2、3 ……n-2、最后一个人】 分两种大情况:
<1> 醉汉先坐你的位置($1/(n-1)$) 那么最后一个人坐错位置的概率为 $1*(1/(n-1))$ = $1/(n-1)$,则坐对位置的概率也为$1/(n-1)$。
<2> 醉汉坐其他人的位置 ( $(n-2)/(n-1)$ ) 假如醉汉坐到了第 x个人的位置,那么从第 2个到第 x-1个人都会坐到自己的位置上。然后剩下的位置第 x个人都可以坐。 或者说情况就变成了:一共 m个人,m个位置(m = n-x+1),每个人都等概率坐任意位置(但还保持那种坐自己位置的特性)。那么最后一个人坐到最后一个位置上的概率就是 1/2(这是个经典的醉汉问题,或者说疯子问题,这里挂一个知乎的链接,就是关于这个问题的若干个解释,不再给出证明知乎醉汉上飞机问题链接 )
这种情况下,最后一个人坐对位置的概率就是$(1/2) * ((n-2)/(n-1))$
那么两种情况相加一下,就是 $1/(n-1)$ + $(1/2) * ((n-2)/(n-1))$ = $n/(2*(n-1))$
代码 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 #include <bits/stdc++.h> using namespace std;#define endl "\n" #define ll long long #define inf 0x3f3f3f3f #define infll 1e15+7 #define IOS ios::sync_with_stdio(0); cin.tie(0) #define debug(a) cout<<"*****\tdebug: " <<a<<"\t*****" <<endl; const double eps = 1e-7 ;const double pi = acos (-1.0 );const int mod = 1e9 +7 ;const int N = 5 + 1e6 ;int main () {#ifndef ONLINE_JUDGE freopen ("in.in" , "r" , stdin); freopen ("out.out" , "w" , stdout); #endif IOS; int n; cin>>n; double ans = 1.0 *n/(2 *(n-1 )); cout<<ans; return 0 ; }
E - Eatcoin 题意 :简单地说,在第 d天,花费 p块钱,生产 $q*d^5$块钱。 生产到 $10^{99}$ 块钱算富豪。每天必须先花费 p块钱才能生产。求开始时最少需要有多少钱,以及在开始时有需要的最少钱的情况下,最少需要多少天才能变成富豪。
题解 :首先要推出 $1^5 + 2^5 + 3^5 + …+n^5$的公式为:$(n^2*(n+1)^2*(2n^2 + 2n-1)) / 12$ 用那个组合数的公式应该也可以(公式证明链接 )
<1> 求开始最少需要多少钱 刚开始花的钱的多,之后生产的钱多。假如到第 x天,生产的钱的总和大于等于花费的钱的总和。所以答案为,前x-1天花费总数 - 前x-1天生产总数 + 第 x天的花费
<2> 求最少需要多少天 列出求手上钱的总数的式子,然后二分天数 即可。
代码 :(python版本, c++版本的大数写的一直有问题,还在debug)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 def cal (n, p, q, x ): return q*(n*n)*(n+1 )*(n+1 )*(2 *n*n+2 *n-1 )//12 - p*n + x p, q = map (int , input ().split()) last = p - q i = 2 while (1 ): now = i*p-q*(i*i)*(i+1 )*(i+1 )*(2 *i*i+2 *i-1 )//12 i += 1 if now >= last: last = now else : print (last+p) break l = 1 r = 10 **100 ans = 0 x = last+p while l <= r: mid = (l+r)//2 if cal(mid, p, q, x) < 10 **99 : l = mid+1 else : r = mid-1 ans = mid print (ans)
J - JavaScript 题意 :模拟 javascript的减法运算。给定两个字符串a b,如果字符串中存在非数字的元素,输出 NaN。否则将两个字符串转为数字,进行相减运算。
题解 :简单模拟即可。(0对应的 ASCLL值为 48)
代码 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 #include <bits/stdc++.h> using namespace std;#define endl "\n" #define ll long long #define inf 0x3f3f3f3f #define infll 1e15+7 #define IOS ios::sync_with_stdio(0); cin.tie(0) #define debug(a) cout<<"*****\tdebug: " <<a<<"\t*****" <<endl; const double eps = 1e-7 ;const double pi = acos (-1.0 );const int mod = 1e9 +7 ;const int N = 5 + 1e3 ;int main () {#ifndef ONLINE_JUDGE freopen ("in.in" , "r" , stdin); freopen ("out.out" , "w" , stdout); #endif string a, b; cin>>a>>b; bool falg = 0 ; for (int i = 0 ; i < a.size (); i++) if (!isdigit (a[i])) falg = 1 ; for (int i = 0 ; i < b.size (); i++) if (!isdigit (b[i])) falg = 1 ; if (falg) cout<<"NaN" ; else { int ans1 = 0 , ans2 = 0 ; for (int i = 0 ; i < a.size (); i++) ans1 = ans1*10 + a[i] - 48 ; for (int i = 0 ; i < b.size (); i++) ans2 = ans2*10 + b[i] - 48 ; cout<<ans1-ans2; } return 0 ; }