目录
B.The Corridor or There and Back Again
链接
一、题目报告
比赛时,做出来了A-D题。比赛后,通过老师讲解完成了A-E题。
二、赛中状况
A题,非常轻松的水掉了。
B题,也非常的简单,但是我因为数组大小开的过小“蛙”掉了一次,悲!
C题,难度也不高,但是因为一些特殊的细节处理不到位,“蛙”了两次,悲上加悲!
D题,一道非常so easy的数学题啊,水掉了。
至于E-G题吗,老师说了,难度有点高,不做了!!!
三、解题报告
A.Two Vessels
题目大意
有分别装有单位水的两个杯子,容量无限大。现在有一个勺子,容量为 ,每次可以从一个杯子里舀一勺不超过单位的水(可以不是整数),放入另一个杯子中。请问最少需要多少次操作才能使两个杯子里的水量相同。
题目解析
非常简单的一道数学题啊!只需要计算出两个杯子之间水量的差,除以2,再去除以去上取整就能得到答案,注意是多组输入!!!
正解代码
#include <cstdio>
#include <string>
#include <iostream>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <stack>
#include <queue>
#include <map>
#include <unordered_map>
#include <vector>
#include <set>
#include <list>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
ll gcd(ll a, ll b) { while (a ^= b ^= a ^= b %= a); return b; }
ll ppow(ll x, ll y) { ll sum = 1; while (y) { if (y & 1) sum *= x; y >>= 1, x *= x; } return sum; }
bool prime(ll x) { for (int i = 2; i * i <= x; i++) { if (x % i == 0) return false; } return true; }
#define bug printf("--------\n");
#define enter printf("\n");
#define debug(x) cout << #x << '=' << x << endl;
#define file(FILENAME) freopen(FILENAME ".in", "r", stdin), freopen(FILENAME ".out", "w", stdout);
#define rep(i, a, b) for(int (i) = (a); (i) <= (b); ++(i))
#define inv(x, mod) ppow((x), (mod) - 2)
#define pb push_back
#define mk make_pair
#define mem(t, v) memset((t), (v), sizeof (t));
#define DBG cerr << __LINE__ << ' ' << __FUNCTION__ << endl;
#define CLOSE ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
#define N 10005
#define M 10005
#define inf 0x3f3f3f3f
#define mod 10007
// ll n, m, l, k, p, i;
// ll a[N], b[N];
// bool vis[N];
// stack<ll> st;
// queue<ll> q;
// map<ll,ll> mp;
// vector<ll> v;
// char c;
// string s;
// ll ans, cnt, sum, num;
// struct node {
// ll x;
// ll y;
// }d[N];
int main() {
// file("")
// CLOSE
ll t;
cin>>t;
while(t--){
ll n,m,k;
cin>>n>>m>>k;
ll dd=labs(n-m)/2.0+0.5;
ll ans=dd/k+(dd%k!=0?1:0);
cout<<ans<<endl;
}
return 0;
}
B.The Corridor or There and Back Again
题目大意
有若干个房间组成一排,给你个有陷阱的房间,每个房间都有编号和陷阱爆炸时间,你必须在陷阱爆炸之前回到这个房间,问你能走到最远的房间是哪。
题目解析
因为通过计算可知你最多可以进入299号房间,所以可以判断每一个房间可以到达的最远的房间号全部之中最小值,即可求出答案。
正解代码
#include <cstdio>
#include <string>
#include <iostream>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <stack>
#include <queue>
#include <map>
#include <unordered_map>
#include <vector>
#include <set>
#include <list>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
ll gcd(ll a, ll b) { while (a ^= b ^= a ^= b %= a); return b; }
ll ppow(ll x, ll y) { ll sum = 1; while (y) { if (y & 1) sum *= x; y >>= 1, x *= x; } return sum; }
bool prime(ll x) { for (int i = 2; i * i <= x; i++) { if (x % i == 0) return false; } return true; }
#define bug printf("--------\n");
#define enter printf("\n");
#define debug(x) cout << #x << '=' << x << endl;
#define file(FILENAME) freopen(FILENAME ".in", "r", stdin), freopen(FILENAME ".out", "w", stdout);
#define rep(i, a, b) for(int (i) = (a); (i) <= (b); ++(i))
#define inv(x, mod) ppow((x), (mod) - 2)
#define pb push_back
#define mk make_pair
#define mem(t, v) memset((t), (v), sizeof (t));
#define DBG cerr << __LINE__ << ' ' << __FUNCTION__ << endl;
#define CLOSE ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
#define N 10005
#define M 10005
#define inf 0x3f3f3f3f
#define mod 10007
// ll n, m, l, k, p, i;
// ll a[N], b[N];
// bool vis[N];
// stack<ll> st;
// queue<ll> q;
// map<ll,ll> mp;
// vector<ll> v;
// char c;
// string s;
// ll ans, cnt, sum, num;
// struct node {
// ll x;
// ll y;
// }d[N];
int main() {
// file("")
// CLOSE
ll t;
cin>>t;
while(t--){
ll n;
ll a[1005];
mem(a,0x3f);
cin>>n;
for(ll i=1;i<=n;i++){
ll x,y;
cin>>x>>y;
a[x]=min(a[x],y);
}
ll k=1000;
ll i=1;
while(i<=k){
if(a[i]<=200){
k=min(i+(a[i]-1)/2,k);
}
i++;
}
cout<<k<<endl;
}
return 0;
}
C.Non-coprime Split
题目大意
给出,构造一组使满足以下条件:
若有多组解,则输出任意一组。
题目解析
简单推理可知,当区间小于等于3时无解,否则当区间长度大于2时,解为区间内的一个偶数的一半,当区间长度为1时,可以判断,这个数不是质数,可以去找一对分解出来的数,这个数是质数是,无解。
正解代码
#include <cstdio>
#include <string>
#include <iostream>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <stack>
#include <queue>
#include <map>
#include <unordered_map>
#include <vector>
#include <set>
#include <list>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
ll gcd(ll a, ll b) { while (a ^= b ^= a ^= b %= a); return b; }
ll ppow(ll x, ll y) { ll sum = 1; while (y) { if (y & 1) sum *= x; y >>= 1, x *= x; } return sum; }
bool prime(ll x) { for (int i = 2; i * i <= x; i++) { if (x % i == 0) return false; } return true; }
#define bug printf("--------\n");
#define enter printf("\n");
#define debug(x) cout << #x << '=' << x << endl;
#define file(FILENAME) freopen(FILENAME ".in", "r", stdin), freopen(FILENAME ".out", "w", stdout);
#define rep(i, a, b) for(int (i) = (a); (i) <= (b); ++(i))
#define inv(x, mod) ppow((x), (mod) - 2)
#define pb push_back
#define mk make_pair
#define mem(t, v) memset((t), (v), sizeof (t));
#define DBG cerr << __LINE__ << ' ' << __FUNCTION__ << endl;
#define CLOSE ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
#define N 10005
#define M 10005
#define inf 0x3f3f3f3f
#define mod 10007
// ll n, m, l, k, p, i;
// ll a[N], b[N];
// bool vis[N];
// stack<ll> st;
// queue<ll> q;
// map<ll,ll> mp;
// vector<ll> v;
// char c;
// string s;
// ll ans, cnt, sum, num;
// struct node {
// ll x;
// ll y;
// }d[N];
int main() {
// file("")
// CLOSE
ll t;
cin>>t;
while(t--){
ll l,r;
cin>>l>>r;
if(l<3)l=3;
if(l>r)cout<<-1<<endl;
else{
if(r-l+1>=2){
while(l&1)l++;
cout<<l/2<<' '<<l/2<<endl;
}
else{
bool flag=0;
for(ll i=2;i*i<=r;i++){
if(r%i==0){
cout<<r/i<<' '<<(i-1)*r/i<<endl;
flag=1;
break;
}
}
if(!flag)cout<<-1<<endl;
}
}
}
return 0;
}
D.Plus Minus Permutation
题目大意
给定三个整数 ,对于 的排列,有
求可能的最大。
题目解析
数学题,可以先计算出能取出多少个与重合的,在计算取出多少个与重合的,利用等差序列公式求解最大值即可。
正解代码
#include <cstdio>
#include <string>
#include <iostream>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <stack>
#include <queue>
#include <map>
#include <unordered_map>
#include <vector>
#include <set>
#include <list>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
ll gcd(ll a, ll b) { while (a ^= b ^= a ^= b %= a); return b; }
ll ppow(ll x, ll y) { ll sum = 1; while (y) { if (y & 1) sum *= x; y >>= 1, x *= x; } return sum; }
bool prime(ll x) { for (int i = 2; i * i <= x; i++) { if (x % i == 0) return false; } return true; }
#define bug printf("--------\n");
#define enter printf("\n");
#define debug(x) cout << #x << '=' << x << endl;
#define file(FILENAME) freopen(FILENAME ".in", "r", stdin), freopen(FILENAME ".out", "w", stdout);
#define rep(i, a, b) for(int (i) = (a); (i) <= (b); ++(i))
#define inv(x, mod) ppow((x), (mod) - 2)
#define pb push_back
#define mk make_pair
#define mem(t, v) memset((t), (v), sizeof (t));
#define DBG cerr << __LINE__ << ' ' << __FUNCTION__ << endl;
#define CLOSE ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
#define N 10005
#define M 10005
#define inf 0x3f3f3f3f
#define mod 10007
// ll n, m, l, k, p, i;
// ll a[N], b[N];
// bool vis[N];
// stack<ll> st;
// queue<ll> q;
// map<ll,ll> mp;
// vector<ll> v;
// char c;
// string s;
// ll ans, cnt, sum, num;
// struct node {
// ll x;
// ll y;
// }d[N];
int main() {
// file("")
// CLOSE
ll t;
cin>>t;
while(t--){
ll n,m,l;
cin>>n>>m>>l;
ll alen=n/m-n/(m*l/gcd(m,l));
ll blen=n/l-n/(m*l/gcd(m,l));
ll ans=((n+(n-alen+1))*alen/2)-((1+blen)*blen)/2;
cout<<ans<<endl;
}
return 0;
}
E.Data Structures Fan
题目大意
给定一个长度为的数组和一个长度为的二进制串现有两个操作:
1 l r
,表示将区间内的所有取反(0 变 1,1 变 0)2 g,
表示将所有的求异或和
题目解析
本题可以使用前缀和做。
在执行所有操作前,先把所有的前缀异或和求出,并且求出与的异或和。
1.取反操作 可以直接让与异或上区间内的前缀和。
2.求和操作 直接输出对应的与即可
正解代码
#include <cstdio>
#include <string>
#include <iostream>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <stack>
#include <queue>
#include <map>
#include <unordered_map>
#include <vector>
#include <set>
#include <list>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
ll gcd(ll a, ll b) { while (a ^= b ^= a ^= b %= a); return b; }
ll ppow(ll x, ll y) { ll sum = 1; while (y) { if (y & 1) sum *= x; y >>= 1, x *= x; } return sum; }
bool prime(ll x) { for (int i = 2; i * i <= x; i++) { if (x % i == 0) return false; } return true; }
#define bug printf("--------\n");
#define enter printf("\n");
#define debug(x) cout << #x << '=' << x << endl;
#define file(FILENAME) freopen(FILENAME ".in", "r", stdin), freopen(FILENAME ".out", "w", stdout);
#define rep(i, a, b) for(int (i) = (a); (i) <= (b); ++(i))
#define inv(x, mod) ppow((x), (mod) - 2)
#define pb push_back
#define mk make_pair
#define mem(t, v) memset((t), (v), sizeof (t));
#define DBG cerr << __LINE__ << ' ' << __FUNCTION__ << endl;
#define CLOSE ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
#define N 100005
#define M 10005
#define inf 0x3f3f3f3f
#define mod 10007
// ll n, m, l, k, p, i;
// ll a[N], b[N];
// bool vis[N];
// stack<ll> st;
// queue<ll> q;
// map<ll,ll> mp;
// vector<ll> v;
// char c;
// string s;
// ll ans, cnt, sum, num;
// struct node {
// ll x;
// ll y;
// }d[N];
ll a[N];
ll sum[N];
int main() {
// file("")
// CLOSE
ll t;
cin>>t;
while(t--){
ll n;
cin>>n;
ll i;
rep(i,1,n)cin>>a[i];
string s;
cin>>s;
ll q;
cin>>q;
ll ans1=0,ans0=0;
mem(sum,0);
for(int i=0;i<n;i++){
if(s[i]=='1')ans1^=a[i+1];
else ans0^=a[i+1];
sum[i+1]=sum[i]^a[i+1];
}
while(q--){
ll opt;
cin>>opt;
if(opt==1){
ll l,r;
cin>>l>>r;
ans0^=(sum[r]^sum[l-1]);
ans1^=(sum[r]^sum[l-1]);
}
else{
char x;
cin>>x;
if(x=='0')cout<<ans0<<' ';
else cout<<ans1<<' ';
}
}
enter
}
return 0;
}
F.Selling a Menagerie
题目大意
动物园里有个动物,第个动物害怕第个动物,第个动物价值元。现在我要将这些动物全部卖掉。显然,卖掉的动物编号可以构成一个排列。
考虑卖掉这些动物时:
- 若在还没有卖掉之前就被卖掉了,现在卖掉,可以获得元;
- 若在还没有卖掉之前没被卖掉,现在卖掉,可以获得元;
构造并输出赚钱最多的动物卖出顺序。
题目解析
既然要求最大值,肯定每次卖出的动物之前没有他害怕的动物最好,所以可以根据他害怕的动物构成一个拓扑数列,每次从中取出没有入的点,肯定最优。
但是这会有个问题,可能会出现一个或者多个环的情况,只需要找到次环中最小值的害怕动物最先取出,后面依次取出即可。
正解代码
#include <cstdio>
#include <string>
#include <iostream>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <stack>
#include <queue>
#include <map>
#include <unordered_map>
#include <vector>
#include <set>
#include <list>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
ll gcd(ll a, ll b) { while (a ^= b ^= a ^= b %= a); return b; }
ll ppow(ll x, ll y) { ll sum = 1; while (y) { if (y & 1) sum *= x; y >>= 1, x *= x; } return sum; }
bool prime(ll x) { for (int i = 2; i * i <= x; i++) { if (x % i == 0) return false; } return true; }
#define bug printf("--------\n");
#define enter printf("\n");
#define debug(x) cout << #x << '=' << x << endl;
#define file(FILENAME) freopen(FILENAME ".in", "r", stdin), freopen(FILENAME ".out", "w", stdout);
#define rep(i, a, b) for(int (i) = (a); (i) <= (b); ++(i))
#define inv(x, mod) ppow((x), (mod) - 2)
#define pb push_back
#define mk make_pair
#define mem(t, v) memset((t), (v), sizeof (t));
#define DBG cerr << __LINE__ << ' ' << __FUNCTION__ << endl;
#define CLOSE ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
#define N 100005
#define M 10005
#define inf 0x3f3f3f3f
#define mod 10007
// ll n, m, l, k, p, i;
// ll a[N], b[N];
// bool vis[N];
// stack<ll> st;
// queue<ll> q;
// map<ll,ll> mp;
// vector<ll> v;
// char c;
// string s;
// ll ans, cnt, sum, num;
// struct node {
// ll x;
// ll y;
// }d[N];
ll a[N],c[N];
ll ru[N];
ll n,i,num;
queue<ll> q;
void huan(ll x){
ll id=x,u=x;
while(a[u]!=x){
u=a[u];
if(c[id]>c[u])id=u;
}
u=a[id];
while(u!=id){
cout<<u<<' ';
ru[u]--;
u=a[u];
}
ru[id]--;
cout<<id<<' ';
}
void tuopo(){
rep(i,1,n)if(ru[i]==0)q.push(i);
while(!q.empty()){
ll u=q.front();
q.pop();
cout<<u<<' ';
num--;
ru[a[u]]--;
if(ru[a[u]]==0)q.push(a[u]);
}
if(num){
rep(i,1,n){
if(ru[i]!=0){
huan(i);
}
}
}
}
int main() {
// file("")
// CLOSE
ll t;
cin>>t;
while(t--){
cin>>n;
num=n;
mem(ru,0);
rep(i,1,n){cin>>a[i];ru[a[i]]++;}
c[0]=inf;
rep(i,1,n)cin>>c[i];
tuopo();
enter
}
return 0;
}
四、总结
本次比赛我并没有完成后三道题目,我觉得不应该,再下一次考试中,我应该更加努力,争取AK!!!
2023.11.4 22:43完成