A. Game with Board
题意
给出n个1,Alice 和 Bob 在这n个1上博弈,每次操作可以选择x个相同的数字(x>1)并把这些数字变成他们的和,不能操作的人输,问最后谁赢了
题解
可以发现在n>=5时候都是Alice赢
code
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define endl "\n"
#define ll long long
#define NO cout<<"NO"<<endl
#define YES cout<<"YES"<<endl
#define rep(i,a,b) for(int i=a;i<=b;i++)
const int mod = 1e9 + 7;
const int N = 2e6 + 10;
ll inf = (1ll << 60);
//priority_queue <int,vector<int>,less<int> > p;
//priority_queue <int,vector<int>,greater<int> > q;
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int T = 1;
cin >> T;
while (T--)
{
int n;cin>>n;
if(n<5) cout<<"Bob"<<endl;
else cout<<"Alice"<<endl;
}
}
B. Keep it Beautiful
题意
给出一个序列a,设刚开始有一个空序列b,遍历a,把a[i]添加到b的末尾,如果添加后的b是一个美丽的序列则真的加入到b并输出1,反之则不加入到b的末尾并输出0
若一个序列是美丽的,则存在一个i,把下标为1-i的所有数按顺序放到该序列的末尾,该序列为不下降序列
题解
模拟整个过程即可,只需考虑是否需要把前面的数挪到后面,末尾的数是什么,要放到末尾的数是什么,第一个数是什么
1.如果之前就已经需要把前面的数挪到后面,若新增的数一定小于等于队首,大于等于队尾,则直接放入
2.如果之前没有把前面的数挪到后面
1)队空或新增数大于等于队尾,直接放入
2)新增数小于等于队首,则直接放入,并确定需要把前面的数挪到后面
code
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define endl "\n"
#define ll long long
#define NO cout<<"NO"<<endl
#define YES cout<<"YES"<<endl
#define rep(i,a,b) for(int i=a;i<=b;i++)
const int mod = 1e9 + 7;
const int N = 2e6 + 10;
ll inf = (1ll << 60);
//priority_queue <int,vector<int>,less<int> > p;
//priority_queue <int,vector<int>,greater<int> > q;
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int T = 1;
cin >> T;
while (T--)
{
int n;
cin >> n;
bool flag = 0;
vector<int> a;
for(int i = 0; i < n; i++){
int x;
cin >> x;
int ans = 0;
if (!flag){
if (a.empty() || x >= a.back()){
a.push_back(x);
ans = 1;
}
else if (x <= a[0]){
a.push_back(x);
ans = 1;
flag = 1;
}
}
else{
if (x >= a.back() && x <= a[0]){
a.push_back(x);
ans = 1;
}
}
cout << ans;
}
cout << '\n';
}
}
C. Ranom Numbers
题意
给出一串由A-E组成的序列s,A-E的贡献为1-10000,若s[i]后存在s[j]使得s[j]>s[i],那么s[i]的贡献为负数,现在可以改变一个字母,求最大得分是多少
题解
对于改变一个字母来讲,只有两种方式
1.在该字母第一次出现时改变
2.在该字母最后一次出现时改变
可证明在中间改变一定不会更优,所以只需枚举改变哪个字母,变成哪个字母即可
code
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define endl "\n"
#define ll long long
#define NO cout<<"NO"<<endl
#define YES cout<<"YES"<<endl
#define rep(i,a,b) for(int i=a;i<=b;i++)
const int mod = 1e9 + 7;
const int N = 2e6 + 10;
ll inf = (1ll << 60);
//priority_queue <int,vector<int>,less<int> > p;
//priority_queue <int,vector<int>,greater<int> > q;
map<char,int>v;
int get(string s)
{
int n=s.size();
int mx=-1;
int ans=0;
for(int i=n-1;i>=0;i--)
{
int x=v[s[i]];
if(x<mx) ans-=x;
else ans+=x;
mx=max(mx,x);
}
return ans;
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int T = 1;
cin >> T;
rep(i,0,4)
{
int x=1;
int t=i;
while(t)
{
t--;
x*=10;
}
v['A'+i]=x;
}
while (T--)
{
string s;
cin>>s;
int n=s.size();
map<char,int>fir,last;
rep(i,0,n-1)
{
if(fir.count(s[i])==0) fir[s[i]]=i;
last[s[i]]=i;
}
int ans=get(s);
rep(i,0,4)
{
char u='A'+i;
if(fir.count(u)==0) continue;
rep(j,0,4)
{
char to='A'+j;
int id=fir[u];
s[id]=to;
ans=max(ans,get(s));
s[id]=u;
id=last[u];
s[id]=to;
ans=max(ans,get(s));
s[id]=u;
}
}
cout<<ans<<endl;
}
}
D. Pairs of Segments
题意
给出n个区间,问最少删去多少个区间可以使剩下来的区间可以两两配对,即只在同一组的两区间中存在交点,不同组的区间不能有交点
题解
换一种思路,可以通过计算最多剩下多少组区间来计算最少需要删去多少个区间
方法如下
首先按照右端点排序,然后只需要记录上一次已配对的右端点和未配对的右端点lastr,只需判断当前线段是否与之前未配队的线段相交,相交则ans++,并且记录当前已配对上的右端点cut,不相交就更新lastr
最后答案就是n-ans*2
code
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define endl "\n"
#define ll long long
#define NO cout<<"NO"<<endl
#define YES cout<<"YES"<<endl
#define rep(i,a,b) for(int i=a;i<=b;i++)
const int mod = 1e9 + 7;
const int N = 2e6 + 10;
ll inf = (1ll << 60);
//priority_queue <int,vector<int>,less<int> > p;
//priority_queue <int,vector<int>,greater<int> > q;
struct node
{
int l,r;
};
node a[N];
bool cmp(node x,node y)
{
return x.r<y.r;
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int T = 1;
cin >> T;
while (T--)
{
int n;cin>>n;
rep(i,1,n) cin>>a[i].l>>a[i].r;
sort(a+1,a+1+n,cmp);
int ans=0;
int cut=-1;
int lastr=-1;
rep(i,1,n)
{
if(a[i].l<=cut) continue;
if(a[i].l<=lastr)
{
ans++;
cut=a[i].r;
}
else
{
lastr=a[i].r;
}
}
cout<<n-ans*2<<endl;
}
}