封面原图 画师やんよ
掉大分的一场 连夜补题 真的不会写啊真的红温了
A - Question Marks
题意
选择题中答案为ABCD的题目各有n道,小明的答案给你,其中?表示这道题空着没写,问他的最高得分
思路
空着的题目肯定没分 超出选项最大个数的肯定也是错的
代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef double db;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;void solve()
{int n;scanf("%d",&n);string s;cin>>s;int A=0,B=0,C=0,D=0;int cnt=0;for(char c: s){if(c=='A') A++;if(c=='B') B++;if(c=='C') C++;if(c=='D') D++;if(c=='?') cnt++;}int ans=s.length();ans-=A-n>0?A-n:0;ans-=B-n>0?B-n:0;ans-=C-n>0?C-n:0;ans-=D-n>0?D-n:0;ans-=cnt;printf("%d\n",ans);
}int main()
{int T=1;scanf("%d",&T);while(T--){solve();}return 0;
}
B - Parity and Sum
题意
给一个数列,每次可以任选两个奇偶性不同的数把其中较小的数变成两个数的和,问至少多少次可以使整个数列的奇偶性相同
思路
每次修改肯定是改出一个奇数,所以除了一开始全是偶数的特判之外我的目标一定是变成奇数,而偶数变成奇数只需要和一个比他的的奇数做题目给出的操作即可,我肯定是尽量要有更多更大的奇数,所以每个偶数都和最大的奇数做操作,如果一直到最后还是有偶数比最大的奇数还大那就操作两次,第一次把奇数变成一个更大的奇数第二次把偶数用这个更大的奇数变成新的奇数即可
代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef double db;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;void solve()
{ll n;scanf("%lld",&n);priority_queue<ll> p;priority_queue<ll,vector<ll>,greater<ll>> q;ll m=0;for(ll i=0;i<n;i++){ll x;scanf("%lld",&x);if(x&1){p.push(x);}else{m=max(m,x);q.push(x);}}if(p.size()==n or q.size()==n){printf("0\n");return;}if(m<p.top()){printf("%d\n",q.size());return;}else{m=q.size()+1;}ll ans=0;while(q.size()){ll a=p.top();ll b=q.top();if(b<a){q.pop();p.push(a+b);}else{p.pop();p.push(a+b);}ans++;}ans=min(ans,m);printf("%lld\n",ans);
}int main()
{int T=1;scanf("%d",&T);while(T--){solve();}return 0;
}
C - Light Switches
题意
有n个开关,一开始都是关的,第一次打开是在 a i a_i ai时刻,之后每 k k k分钟按一次,问最早什么时候所有开关都是开的状态
思路
首先我们要找的时间一定比最后开的开关还靠后,我们的第一步是先要统一我们要找的区间(检查他是否能够让所有开关都打开)的起点,但是实际上前面部分开关开的时间覆盖的区间的起点可能在这一段之前,所以我们要先往右边移动两格,第一次是移动到最右边的第一个关灯的位置,然后再移到下一个开灯的位置,注意在这里判断每个灯之前开关灯次数的奇偶性判断到底要不要在这里多开关一次统一灯的状态,具体看一下这个图
然后我们再判断我们找到的这个区间有没有机会满足所有开关都打开就可以了
代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef double db;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;void solve()
{ll n,k;scanf("%lld%lld",&n,&k);vector<ll> a(n);for(ll i=0;i<n;i++){scanf("%lld",&a[i]);}sort(a.begin(),a.end());ll t=a.back();//最大值for(int i=0;i<n;i++){ll cnt=1ll+(a.back()-a[i])/k;if(cnt%2ll==0ll)t=max(t,a[i]+cnt*k);}ll _t=t;for(int i=0;i<n;i++){ll cnt=1ll+(t-a[i])/k;if(cnt%2ll==0ll)_t=max(_t,a[i]+cnt*k);}for(int i=0;i<n;i++){ll cnt=1ll+(_t-a[i])/k;if(cnt%2ll==0ll){printf("-1\n");return ;}}printf("%lld\n",_t);
}int main()
{int T=1;scanf("%d",&T);while(T--){solve();}return 0;
}