VII MaratonUSP Freshman Contest
A. Abducting Nathan!
每得2k
分会轮回,模2k
后,小于k先手,反之后手
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int read(){
int x = 0 , ch = getchar();
while( ch < '0' || ch > '9' ) ch = getchar();
while( ch >= '0' && ch <= '9' ) x = (x<<3)+(x<<1) + ch - '0' , ch = getchar();
return x;
}
void solve(){
ll k = read() , t = read() , n = read();
ll p = ( t + n ) % ( k * 2 );
if( p < k ) printf("Thiago\n");
else printf("Nathan\n");
return ;
}
int main(){
for( int t = read() ; t ; t -- )
solve();
return 0;
}
B. Best University ID
找哪个人的最大质因子最大。先求出1e4
以内的素数,然后试除法即可。
#include<bits/stdc++.h>
using namespace std;
const int N = 1e4+5;
bitset<N> notPrime;
vector<int> prime;
void getPrime(){
notPrime[0] = notPrime[1] = true;
for( int i = 2 ; i < N ; i ++ ){
if( notPrime[i] == false ) prime.push_back(i);
for( auto j : prime ){
if( j * i >= N ) break;
notPrime[ j*i ] = true;
}
}
}
int getVal( int x ){
int t = 0;
for( auto i : prime ){
if( x % i != 0 ) continue;
t = i;
while( x % i == 0 ) x /= i;
if( x == 1 ) break;
}
return max( t , x );
}
int main(){
getPrime();
int n , val = 0;
cin >> n;
string res , s;
for( int i = 1 , id , t ; i <= n ; i ++ ){
cin >> s >> id;
t = getVal(id);
if( t > val ) val = t , res = s;
}
cout << res;
return 0;
}
C. CCM
\(v_{ma}\)是无用变量,因为\(r_{ca}>r_{cr} \and r_{ca} > r_{ma}\),所以\(v_{ca} > v_{cr}\)一定成立。因为三人的三角形是等腰三角形,所以Marcel的气球一定是于Carlinhos相遇。所以之间判断Carlinhos的气球是否大于Marcel到Carlinhos距离的一半即可。因此可以二分出最小速度。
#include<bits/stdc++.h>
using namespace std;
#define double long double
double x , y , d , vcr , vma;
bool check( double v ){
if( x * v / ( v + vcr ) >= d * 0.5 ) return true;
return false;
}
int32_t main(){
cin >> x >> y >> vcr >> vma;
d = sqrt( y * y + x * x / 4.0 );
double l = vcr , r = 1e18 , mid;
for( int t = 500 ; t ; t -- ){
mid = ( l + r ) * 0.5;
if( check(mid) ) r = mid;
else l = mid;
}
cout << setprecision(15) << fixed << ( l + r ) * 0.5 << "\n";
return 0;
}
D. Diary of Hapiness
求和,判断和与0的关系
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int read(){
int x = 0 , f = 1 , ch = getchar();
while( (ch < '0' || ch > '9') && ch != '-' ) ch = getchar();
if( ch == '-' ) f = -1 , ch = getchar();
while( ch >= '0' && ch <= '9' ) x = (x<<3)+(x<<1) + ch - '0' , ch = getchar();
return x * f;
}
int main(){
int res = 0;
for( int x , n = read() ; n ; n -- )
x = read() , res += x;
if( res > 0 ) printf(":)\n");
else if( res == 0 ) printf(":|\n");
else printf(":(\n");
return 0;
}
E. El Classificador
multiset
+lower_bound
实现
#include<bits/stdc++.h>
using namespace std;
#define int long long
int read(){
int x = 0 , f = 1 , ch = getchar();
while( (ch < '0' || ch > '9') && ch != '-' ) ch = getchar();
if( ch == '-' ) f = -1 , ch = getchar();
while( ch >= '0' && ch <= '9' ) x = (x<<3)+(x<<1) + ch - '0' , ch = getchar();
return x * f;
}
int32_t main(){
int n = read() , q = read();
multiset<int> st;
for( int x ; n ; n -- ) x = read() , st.insert(x);
for( int x ; q ; q -- ){
x = read();
auto it = st.lower_bound(x);
if( it != st.end() && *it >= x ) printf("%lld\n" , *it ) , st.erase(it);
else printf("-1\n");
}
}
F. Food Queue
很好队列后贪心的选择用时最少的即可
#include<bits/stdc++.h>
using namespace std;
#define int long long
int read(){
int x = 0 , f = 1 , ch = getchar();
while( (ch < '0' || ch > '9') && ch != '-' ) ch = getchar();
if( ch == '-' ) f = -1 , ch = getchar();
while( ch >= '0' && ch <= '9' ) x = (x<<3)+(x<<1) + ch - '0' , ch = getchar();
return x * f;
}
int32_t main(){
int n = read() , m = read() , cnt = 0;
array<vector<int>,4> q;
char s[3];
for( int t ; n ; n -- ){
scanf("%s" , s ) , t = read();
if( s[0] == 'C' ) q[0].push_back(t);
else if( s[0] == 'F' ) q[1].push_back(t);
else if( s[0] == 'P' ) q[2].push_back(t);
else q[3].push_back(t);
}
for( auto it : q ){
sort( it.begin() , it.end() );
int p = m;
for( auto t : it ){
if( t > p ) break;
p -= t , cnt ++;
}
}
cout << cnt;
}
G. Grand Meeting
找到两人所在车站之间的距离,距离的一半就是花费时间,注意上取整
#include<bits/stdc++.h>
using namespace std;
int main(){
int n;
string s , c , m;
cin >> n;
map<string,int> stations;
for( int i = 1 ; i <= n ; i ++ )
cin >> s , stations[s] = i;
cin >> c >> m;
int dis = abs(stations[c] - stations[m]);
cout << (dis / 2 + dis % 2 ) << '\n';
return 0;
}
H. Harada Football Clube
至少要有四个人,且门将只能有一个,所以剩下的人分成三种职业,即求\(x+y+z=(n-4),x\ge0,y\ge0,z\ge0\)解的个数。可以转化为\(x+y+z=(n-4)+3,x\ge1,y\ge1,z\ge1\)的方案数。隔板法\(C_{(n-4)+3-1}^{2}\)
#include<bits/stdc++.h>
using namespace std;
#define int long long
int32_t main(){
int n; cin >> n ; n -= 2;
cout << n * (n-1) / 2;
}
I. Irritating Carlinhos
直接模拟一下就好
#include<bits/stdc++.h>
using namespace std;
int main(){
map<char,int> dx,dy;
dx['U'] = 0 , dy['U'] = 1;
dx['D'] = 0 , dy['D'] = -1;
dx['R'] = 1 , dy['R'] = 0;
dx['L'] = -1 , dy['R'] = 0;
int cx , cy , tx , ty , n ;
string opt , opc;
cin >> tx >> ty >> cx >> cy >> opt >> opc;
n = opt.size();
if( cx == tx && cy == ty ) cout << "Rodou!\n" , exit(0);
for( int i = 0 ; i < n ; i ++ ){
tx += dx[ opt[i] ] , ty += dy[ opt[i] ];
if( cx == tx && cy == ty ) cout << "Rodou!\n" , exit(0);
cx += dx[ opc[i] ] , cy += dy[ opc[i] ];
if( cx == tx && cy == ty ) cout << "Rodou!\n" , exit(0);
}
cout << "Quase!\n";
return 0;
}
J. Journey through time
直接res[i][0/1/2]
表示第i
次操作后的最大值、最小值、元素和,然后递推的维护一下就好
#include<bits/stdc++.h>
using namespace std;
#define int long long
int read(){
int x = 0 , f = 1 , ch = getchar();
while( (ch < '0' || ch > '9') && ch != '-' ) ch = getchar();
if( ch == '-' ) f = -1 , ch = getchar();
while( ch >= '0' && ch <= '9' ) x = (x<<3)+(x<<1) + ch - '0' , ch = getchar();
return x * f;
}
int32_t main(){
int n = read();
vector< array<int,3> > res(n+1);
res[0][0] = LLONG_MIN , res[0][1] = LLONG_MAX , res[0][0] = 0;
for( int i = 1 , op, t ; i <= n ; i ++ ){
op = read() , t = read();
if( op == 1 ) res[i][0] = max( res[i-1][0] , t ) , res[i][1] = min( res[i-1][1] , t ) , res[i][2] = res[i-1][2] + t;
else op -= 2 , res[i] = res[i-1] , printf( "%lld\n" , res[t][op] );
}
return 0;
}