2020.03.14 Preliminaries for BAPC 2019 解题报告
B
题意
就是让你通过给你的规律,来把一行公式进行求值
思路
通过看题面上的规律, 我们可以知道第一行是+,第二行是*,第三行是+and so on ...,所以我们只要把对应位置的数字用对应的符号进行运算就行
代码
#include<iostream>
#include<string>
#include<cstring>
#include<algorithm>
#include<cstdio>
#include<cmath>
#include<set>
#include<map>
#include<vector>
#include<queue>
#include<sstream>
using namespace std;
#define sf scanf
#define pf printf
#define pfn printf("\n");
#define pfk printf(" ");
#define pf0 printf("0");
#define pf1 printf("1");
#define ll long long
//#define ll __int128
#define ull unsigned long long
#define sfd(n) scanf("%d",&n);
#define sfdd(n,m) scanf("%d%d",&n,&m);
#define sfld(n) scanf("%lld",&n);
#define sfldd(n,m) scanf("%lld%lld",&n,&m);
#define sflf(n) scanf("%lf",&n);
#define sflff(n,m) scanf("%lf%lf",&n,&m);
#define sfc(n) scanf("%c",n);
#define sfcc(n,m) scanf("%c%c",n,m);
#define sfs(n) scanf("%s",n);
#define sfss(n,m) scanf("%s%s",n,m);
#define pfd(n) printf("%d",n);
#define pfld(n) printf("%lld",n);
#define pflf(n) printf("%lf",n);
#define pfc(n) printf("%c",n);
#define pfs(n) printf("%s",n);
#define csh(a,n) memset(a,n,sizeof(a));
vector<ll>brr[300010],crr;
ll mod=1000000007;
int main()
{
int n;
cin>>n;
int p=0;
while(n--){
char a[100];
cin>>a;
if(a[0]=='('){
p++;
}
else if(a[0]==')'){
ll b=0;
if(p%2==0){
for(int i=0;i<brr[p].size();i++){
b+=brr[p][i];
b%=mod;
}
brr[p].clear();
}
else{
b=1;
for(int i=0;i<brr[p].size();i++){
b*=brr[p][i];
b%=mod;
}
brr[p].clear();
}
p--;
brr[p].push_back(b);
}
else{
ll b=0;
for(int i=0;i<strlen(a);i++){
b*=10;
b+=a[i]-'0';
}
b%=mod;
brr[p].push_back(b);
}
}
ll b=0;
for(int i=0;i<brr[0].size();i++){
b+=brr[0][i];
b%=mod;
}
cout<<b<<endl;
return 0;
}
D
题意
问你一个(n面的)骰子投出K次后,最大的期望是多少
思路
首先我们通过题面知道每次投骰子都有两种情况
- 让骰子停止转动(就是不投)
- 重新转动骰子
所以我们只要考虑一件事情就行,就是当前的点数与上次的点数的大小 (设一开始期望是E1:$\frac{1+2+...+n}{n} $)
- 如果当前的小于的话,那我们就不需要本次的点数即停止骰子转动 -> $\frac{E1*E1}{n} $
- 反之,则取当前的点数 -> $\frac{E1+1+E1+2+...+n}{n} $
最后整理一下就可以了
代码
#include<bits/stdc++.h>
using namespace std;
int main()
{
double n,ans=0,t=0;
int k;
cin>>n>>k;
while(k--)
{
ans=(ans*t+n*(n+1)/2-t*(t+1)/2)/n;
t=floor(ans);
}
printf("%.9f\n",ans);
return 0;
}
E
题意
问你是否可以使图没有回环
思路
因为题面说了,最多删除n/2个边所以只要判断
- 从小到大的边和从大到小的边 的数量即可
- 输出多的(这样删去后保证了没有回环存在)
代码
#include <vector>
#include <algorithm>
#include <string>
#include<cstring>
#include <iostream>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <unordered_map>
#include <bitset>
#include <cassert>
#include <chrono>
#include <random>
#include <iomanip>
#include <unordered_set>
#include <ctime>
#include <chrono>
using namespace std;
// #define ll long long
const int N =1e5+10;
#define all(x) (x).begin(),(x).end()
#define rall(x) (x).rbegin(),(x).rend()
#define pb push_back
#define sz(x) (int)(x).size()
typedef long long ll;
typedef long double ld;
mt19937 rnd(chrono::high_resolution_clock::now().time_since_epoch().count());
ll n , m ,t ;
int f[1000010],br[2000010];
int s[2000010]={0};
bool st[N];
ll mod = 1e9+7;
int main(){
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
cin >>n>>m;
vector<int > s1, s2;
for(int i=0;i<m;i++) {
int a, b;cin >>a>>b;
if(a<b)s1.pb(i+1);
else s2.pb(i+1);
}
if(sz(s1)> sz(s2)){
cout<<sz(s2)<<endl;
for(auto it:s2)cout<<it<<" ";
cout<<endl;
}
else {
cout<<sz(s1)<<endl;
for(auto it:s1)cout<<it<<" ";
cout<<endl;
}
return 0;
}
/*
* 5
4 100
0 0 0 0
1 2
1
3 4
1 4 1
3 2
0 1 3
3 9
0 59049 810
*/
I
题意
很直接,问你$$ n = m{2}-k $$,是否存在
- 存在输出n和m
- 不存在输出0
思路
暴力
- 因为 $$n = m{2}-k \longleftrightarrow n =(m-k)*(m+k) $$ ,即(m-k) 和(m+k)是n的因数,所以先求出n的所有因数
- 然后双重for寻找满足的m,k
代码
#include <vector>
#include <algorithm>
#include <string>
#include<cstring>
#include <iostream>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <unordered_map>
#include <bitset>
#include <cassert>
#include <chrono>
#include <random>
#include <iomanip>
#include <unordered_set>
#include <ctime>
#include <chrono>
using namespace std;
// #define ll long long
const int N =1e5+10;
#define all(x) (x).begin(),(x).end()
#define rall(x) (x).rbegin(),(x).rend()
#define pb push_back
#define sz(x) (int)(x).size()
typedef long long ll;
typedef long double ld;
mt19937 rnd(chrono::high_resolution_clock::now().time_since_epoch().count());
int n , m ,t ;
int ar[1000010],br[200010];
int f[2010][2010]={0};
bool st[N];
ll mod = 1e9+7;
int main(){
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
cin >>n;
ll num =0 ,cnt =0 ;
for(int i=1;i<=n;i++){
cin >>ar[i];
if(i>=2)cnt+=ar[i];
else num=ar[i]*ar[i] +num ;
}
//cout<<num<<" "<<cnt<<endl;
ll sum =num*cnt ;
for(int i=2;i<=n;i++){
num=ar[i]*ar[i] +num;
cnt -= ar[i];
// cout<<num<<" "<<cnt<<endl;
sum = max(sum , num*cnt);
// sum = num*cnt;
}
cout <<sum<<endl;
//cout<<sum<<endl;
return 0;
}
/*
* 5
4 100
0 0 0 0
1 2
1
3 4
1 4 1
3 2
0 1 3
3 9
0 59049 810
*/