目录
A - Olympic Ranking
题意:n支队伍,各有一定数量的金牌,银牌,铜牌。按照金牌 > 银牌 > 铜牌的优先级,找出最强的队伍。
题解:题意简单,难点在于输入那个字符串。
<1> 使用 getline和 string配合,然后输出的时候从第 1位输出而不是第 0位,会 wa12。
<2> 我是手写了一个输入字符串的函数。
<3> 我队友用的 map + tuple + string,也把代码附上,可以做个参考。(%%%
代码:<2>
#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
// IOS;
// ---------------------------------------------------------------
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
题意:求一个数的因子之和(除了自己本身),然后和自身比大小,对应输出三种字符串。
题解:预处理一下即可。
代码:
#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
// IOS;
// ---------------------------------------------------------------
for(int i = 1; i < 1000010; i++)
for(int j = 2*i; j < 1000010; j += i)
ans[j] += i;
// for(int i = 1; i <= 20; i++) cout<<ans[i]<<endl;
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
题意:给定一个数组,求逆序对数。
题解:板子题,树状数组跑一遍即可。
代码:
#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/(n-1)
1/(n−1))
那么最后一个人坐错位置的概率为
1
∗
(
1
/
(
n
−
1
)
)
1*(1/(n-1))
1∗(1/(n−1)) =
1
/
(
n
−
1
)
1/(n-1)
1/(n−1),则坐对位置的概率也为
1
/
(
n
−
1
)
1/(n-1)
1/(n−1)。
<2> 醉汉坐其他人的位置 (
(
n
−
2
)
/
(
n
−
1
)
(n-2)/(n-1)
(n−2)/(n−1) )
假如醉汉坐到了第 x个人的位置,那么从第 2个到第 x-1个人都会坐到自己的位置上。然后剩下的位置第 x个人都可以坐。
或者说情况就变成了:一共 m个人,m个位置(m = n-x+1),每个人都等概率坐任意位置(但还保持那种坐自己位置的特性)。那么最后一个人坐到最后一个位置上的概率就是 1/2(这是个经典的醉汉问题,或者说疯子问题,这里挂一个知乎的链接,就是关于这个问题的若干个解释,不再给出证明知乎醉汉上飞机问题链接)
这种情况下,最后一个人坐对位置的概率就是 ( 1 / 2 ) ∗ ( ( n − 2 ) / ( n − 1 ) ) (1/2) * ((n-2)/(n-1)) (1/2)∗((n−2)/(n−1))
那么两种情况相加一下,就是 1 / ( n − 1 ) 1/(n-1) 1/(n−1) + ( 1 / 2 ) ∗ ( ( n − 2 ) / ( n − 1 ) ) (1/2) * ((n-2)/(n-1)) (1/2)∗((n−2)/(n−1)) = n / ( 2 ∗ ( n − 1 ) ) n/(2*(n-1)) n/(2∗(n−1))
代码:
#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 q*d^5 q∗d5块钱。 生产到 1 0 99 10^{99} 1099 块钱算富豪。每天必须先花费 p块钱才能生产。求开始时最少需要有多少钱,以及在开始时有需要的最少钱的情况下,最少需要多少天才能变成富豪。
题解:首先要推出
1
5
+
2
5
+
3
5
+
.
.
.
+
n
5
1^5 + 2^5 + 3^5 + ...+n^5
15+25+35+...+n5的公式为:
(
n
2
∗
(
n
+
1
)
2
∗
(
2
n
2
+
2
n
−
1
)
)
/
12
(n^2*(n+1)^2*(2n^2 + 2n-1)) / 12
(n2∗(n+1)2∗(2n2+2n−1))/12
用那个组合数的公式应该也可以(公式证明链接)
<1> 求开始最少需要多少钱
刚开始花的钱的多,之后生产的钱多。假如到第 x天,生产的钱的总和大于等于花费的钱的总和。所以答案为,前x-1天花费总数 - 前x-1天生产总数 + 第 x天的花费
<2> 求最少需要多少天
列出求手上钱的总数的式子,然后二分天数即可。
代码:(python版本, c++版本的大数写的一直有问题,还在debug)
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 # 不要x也能过,答案太大,x没影响?
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)
代码:
#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
// IOS;
// ---------------------------------------------------------------
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;
}