A.Surrender to My Will
题意:
给你5人的是否投降状态,Y是投降,N是不投降,-是没有选择。
让你判断最后结果。
题解:
四人已经投降了就投降了,两人没有投降就是拒绝投降,其他情况是不明确。
代码:
#include<bits/stdc++.h>
using namespace std;
typedef __int128 i128;
typedef long long ll;
typedef double db;
const db PI = acos(-1);
typedef array<ll, 2> PII; // vector<PII> a(n + 1);
const ll inf = 2e18 + 10;
const int mod = 998244353;
const int maxn = 2e5 + 10;
bool multi = 0;
void Solve() {
string s; cin >> s;
ll cnt = 0, cnt1 = 0;
for(auto i : s) {
if(i == 'Y') cnt ++ ;
if(i == 'N') cnt1 ++ ;
}
if(cnt >= 4) {
cout << "1\n";
} else if(cnt1 >= 2) {
cout << "-1\n";
} else cout << "0\n";
}
signed main() {
// freopen("test.in","r",stdin);
// freopen("code.out","w",stdout);
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
ll T = 1;
if(multi) cin >> T;
while(T -- ) {
Solve();
}
return 0;
}
B.std::pair
题意:
给定n个类型 和成员名称。
类型只能是pair嵌套int或者pair或者double。
q次询问,每次询问给定成员名称的用法,输出询问的类型。
例如xxx.first.second,就是xxx的pair嵌套的第一个的第二个。
题解:
思路简单,就是一道模拟题。
xxx.first.second……,我们提取出成员名称,每个**.**后是字母
f
f
f就是第一个,
s
s
s就是第二个。
pair<first,second>,‘<’ 符号后是第一个类型 ,‘,’ 符号后是第二个类型。
一个pair要有 ‘<’,‘>’ ,才算完整。
例如:嵌套的pair<pair<int,double>,int>找第二个,要完整的跳过第一个后的 ‘,’ 才是第二个。
代码:
#include <bits/stdc++.h>
#ifndef ONLINE_JUDGE
#include "_my_utils.h"
#endif
#define int long long
#define new _MY_NEW_
#define lg(ITEM) static_cast<int>(std::log2(ITEM))
using namespace std;
using ll = long long;
using PII = array<int, 2>;
constexpr long long INF = 2E18 + 10;
constexpr int N = 2E6 + 10;
void SINGLE_TEST() {
int n, q;
cin >> n >> q;
unordered_map<string, string> ty;
cin.ignore();
for (int i = 1; i <= n; i++) {
string s;
getline(cin, s);
auto p = s.find(' ');
string temp = s.substr(p + 1);
temp.pop_back();
ty[temp] = s.substr(0, p);
}
while (q--) {
string s;
cin >> s;
int las = 1;
if (s.find('.') != string::npos) {
string name = s.substr(0, s.find('.'));
string tp = ty[name];
int p = 0;
string t = s.substr(s.find('.'));
int now = 0;
int nu = 0;
for (int i = 0; i < t.size(); i++) {
if (t[i] != '.') continue;
nu++;
if (t[i + 1] == 'f') {
las = 1;
now = 0;
while (p < tp.size() && !(now == 0 && tp[p] == '<')) {
if (tp[p] == '<') now++;
if (tp[p] == '>') now--;
p++;
}
// COUT(p)
} else {
las = 2;
now = 0;
while (p < tp.size() && !(now == 1 && tp[p] == ',')) {
if (tp[p] == '<') now++;
if (tp[p] == '>') now--;
p++;
}
// COUT(p)
}
p++;
}
// COUT(p)
string ans;
if (las == 1) {
int t = 0;
for (int i = p; i < tp.size(); i++) {
if (tp[i] == '<') t++;
if (tp[i] == '>') t--;
if (t == 0 && tp[i] == ',') {
ans = tp.substr(p, i - p);
break;
}
}
} else {
int t = 0;
for (int i = p; i < tp.size(); i++) {
if (tp[i] == '<') t++;
if (tp[i] == '>') t--;
if (t == -1 && tp[i] == '>') {
ans = tp.substr(p, i - p);
break;
}
}
}
cout << ans << "\n";
} else {
cout << ty[s] << '\n';
}
}
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(nullptr), cout.tie(nullptr);
int SAMPLES = 1;
// cin >> SAMPLES;
for (int CUR = 1; CUR <= SAMPLES; CUR++) {
SINGLE_TEST();
}
}
H.All-in at the Pre-flop
题意:
有一个
n
×
n
n \times n
n×n的矩阵,按循序给
n
×
n
n \times n
n×n个点。
不能出现任何三点共线。这个点能插入就输出1,不能就输出0.
题解:
插入点时,当现在已经插入cnt个点,点与之前插入的点形成的直线,在矩阵上的点都标记为不能插入。
插入点(x,y)与之前已经插入的点,在x轴,y轴上差值,除gcd后的(dx,dy),点
(
x
+
k
∗
d
x
,
y
+
k
∗
d
y
)
(x+k*dx,y+k*dy)
(x+k∗dx,y+k∗dy)都在一条直线上,把在矩阵中的点都标记为不能插入,剩下的点就是下一个点能插入的位置。
代码:
//#pragma GCC optimize(2)
#include <bits/stdc++.h>
//#define int long long
#define YCJ ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
#define PII pair<int,int>
#define PIII pair<pair<int,int>,int>
typedef long long ll;
using namespace std;
const int N = 10000010;
int n,x,y;
bool mp[1010][1010];
int xx[1010 * 1010],yy[1010 * 1010];
int cnt = 0;
signed main()
{
YCJ;
cin >> n;
for(int i = 1;i <= n * n;i++)
{
cin >> x >> y;
if(mp[x][y] == 0)
{
cout << "1";
for(int i = 1;i <= cnt;i++)
{
int dx = x - xx[i];
int dy = y - yy[i];
int g = __gcd(dx,dy);
dx/=g,dy/=g;
int px = x,py = y;
while(px > 0 && px <= n && py > 0 && py <= n)
{
mp[px][py] = 1;
px += dx;
py += dy;
}
px = x,py = y;
while(px > 0 && px <= n && py > 0 && py <= n)
{
mp[px][py] = 1;
px -= dx;
py -= dy;
}
}
cnt++;
xx[cnt] = x;
yy[cnt] = y;
}
else
{
cout << "0";
}
}
return 0;
}
K.Doremy's IQ 2
题意:
n场比赛,每场比赛难度为
a
i
a_i
ai,初始智力为0。
当比赛难度低于当前智力,智力-1
当比赛难度高于当前智力,智力-1
当比赛难度等于当前智力,满足感+1
每次比赛只有一场。
求满足感最大值
题解:
很典的二分,他能玩比赛难度和智力相等的场次只可能靠近0,并且连续的。
我们二分能相等难度的比赛场数,然后遍历一遍区间为mid的子区间,判断是否存在就行。
一个区间内要可以难度等于智力,
[
l
…
…
r
]
[l……r]
[l……r],假如
l
l
l为负,
r
r
r为正,可以考虑先让智力变为负数,在变为正数,或者先让智力变为正数,在变为负数,判断区间左边,右边的数量是否可以完成就行。
代码:
#include <bits/stdc++.h>
//#define int long long
#define PII pair<int,int>
using namespace std;
const int N =2e6+6;
int a[N];
void solve()
{
int n,q;
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
}
int x=0,y=0,f=0,ans=0;
int l=0,r=n,mid,i;
while(l<r){
mid=(l+r+1)/2;
f=0;
for(int j=mid;j<=n;j++){
i=j-mid+1;
if(a[i]<0){
if(i-1>=-a[i]){
if(a[j]>0){
if(n-j>=(a[j]-a[i]))f=1;
}else f=1;
}
}
//->
if(a[j]>=0){
if(n-j>=a[j]){
if(a[i]<0){
if(i-1>=-(a[i]-a[j]))f=1;
}else f=1;
}
}
}
if(f){
l=mid;
}else r=mid-1;
}
cout<<l<<'\n';
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr), cout.tie(nullptr);
int T=1;
cin>>T;
while(T--){
solve();
}
return 0;
}