这是我做过的最sb的一场div2,没AK有点可惜,F有些小trick
670A holidays
根据%7的结果判一下就好了
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<iostream>
#include<vector>
#include<set>
#include<queue>
#include<algorithm>
#include<stack>
#include<string>
#define MAX 200000
#define INF 0x3f3f3f3f
using namespace std;
typedef long long LL;
int dp[MAX+10];
int num[MAX+10];
int main(void)
{
int n,t;
scanf("%d",&n);
int mx=(int)(n/7)*2;
mx+=min(n%7,2);
int mn=(int)(n/7)*2;
mn+=max(0,n%7-5);
printf("%d %d\n",mn,mx);
return 0;
}
670BGame of Robots
搞清楚是第几个人在报数和报到第几个数就好了,是一个等差数列前n项和,然后xjbg
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<iostream>
#include<vector>
#include<set>
#include<queue>
#include<algorithm>
#include<stack>
#include<string>
#define MAX 200000
#define INF 0x3f3f3f3f
using namespace std;
typedef long long LL;
LL nn[MAX+10];
LL num[MAX+10];
int siz=0;
void init(){
num[1]=1;
for(int i=2;i<=100010;i++){
num[i]=num[i-1]+(LL)i;
if(num[i]>2000000100LL)break;
siz=i;
}
}
int main(void)
{
init();
LL n,k;
scanf("%I64d %I64d",&n,&k);
for(int i=1;i<=n;i++){
scanf("%I64d",&nn[i]);
}
LL ans=0;
int pp=lower_bound(num+1,num+1+siz,k)-num;
if(num[pp]==k){
ans=nn[pp];
}
else ans=nn[k- num[pp-1]];
printf("%I64d\n",ans);
return 0;
}
670C-Cinema
map搞一下,然后统计下就好了,用unordered_map不调参会被卡,数组别开小了
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<iostream>
#include<vector>
#include<set>
#include<map>
#include<queue>
#include<algorithm>
#include<stack>
#include<string>
#define Max 600000
#define INF 0x3f3f3f3f
using namespace std;
typedef long long LL;
map<int,int>mp;
int a[Max+10];
int b[Max+10];
int c[Max+10];
int vis1[Max+10];
int siz=0;
void add(int p){
if(!mp.count(p))mp[p]=++siz;
}
int main(void)
{
int n,m;
scanf("%d",&n);
memset(vis1,0,sizeof(vis1));
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
add(a[i]);
vis1[mp[a[i]]]++;
}
scanf("%d",&m);
for(int i=1;i<=m;i++){
scanf("%d",&b[i]);
add(b[i]);
}
for(int i=1;i<=m;i++){
scanf("%d",&c[i]);
add(c[i]);
}
int mn1,mn2;
int flag=1;
mn1=mn2=-1;
for(int i=1;i<=m;i++){
if(vis1[mp[b[i]]]>mn1){
mn1=vis1[mp[b[i]]];
mn2=vis1[mp[c[i]]];
flag=i;
}
else if(vis1[mp[b[i]]]==mn1){
if(vis1[mp[c[i]]]>mn2){
mn2=vis1[mp[c[i]]];
flag=i;
}
}
}
printf("%d\n",flag);
return 0;
}
670D1,D2-Magic Powder - 2
二分答案,判是否可行
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<iostream>
#include<vector>
#include<set>
#include<queue>
#include<algorithm>
#include<stack>
#include<string>
#define MAX 200000
#define INF 0x3f3f3f3f
using namespace std;
typedef long long LL;
LL a[MAX];
LL b[MAX];
int main(void)
{
LL n,k;
scanf("%I64d%I64d",&n,&k);LL ans=0;
for(int i=1;i<=n;i++)scanf("%I64d",&a[i]);
for(int i=1;i<=n;i++)scanf("%I64d",&b[i]);
LL l=0;
LL r=2000000010;
while(l<=r){
LL mid=((l+r)>>1);
LL sum=0;
int flag=1;
for(int j=1;j<=n;j++){
if(a[j]*mid>b[j]){
sum+=(a[j]*mid-b[j]);
if(sum>k){
r=mid-1;
flag=0;
break;
}
}
}
if(!flag)continue;
ans=max(mid,ans);
l=mid+1;
}
printf("%I64d\n",ans);
return 0;
}
670E-Correct Bracket Sequence Editor
先匹配一下括号,光标移动和删除用链表模拟就好了
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<iostream>
#include<vector>
#include<set>
#include<queue>
#include<algorithm>
#include<stack>
#include<string>
#define MAX 200000
#define INF 0x3f3f3f3f
using namespace std;
typedef long long LL;
char str[500050];
int st[500050];
int pp[500050];
char op[500050];
int fst=0;
struct node{
int l,r;
}lst[500050];
int main(void)
{
int n,m,p;
scanf("%d%d%d",&n,&m,&p);
scanf("%s",str+1);
for(int i=1;i<=n;i++){
if(str[i]=='(')st[++fst]=i;
else {
pp[i]=st[fst--];
pp[pp[i]]=i;
}
}
for(int i=0;i<=n;i++){
lst[i].l=i-1;
lst[i].r=i+1;
}
scanf("%s",op+1);
for(int i=1;i<=m;i++){
if(op[i]=='R')p=lst[p].r;
else if(op[i]=='L')p=lst[p].l;
else {
if(p>pp[p])p=pp[p];
int ll=lst[p].l;
int rr=lst[pp[p]].r;
lst[ll].r=rr;
lst[rr].l=ll;
p=rr;
if(p==n+1)p=ll;
}
}
for(int i=lst[0].r;i!=n+1;i=lst[i].r){
printf("%c",str[i]);
}
puts("");
return 0;
}
670F-Restore a Number
有点烦的一道模拟
先通过观察原串的长度的范围可以确定原串的长度,然后去掉不相干的数字,然后从小向大输出。
前导零我判的比较麻烦,我是首先找到一个除了字串以外最小不为0的数,然后判断这个和字串的大小。
1.如果大于子串首字母,就先放子串
2.如果小于子串首字母,就先放这个字符。
3.如果等于子串首字母,判一下子串比不比这个字符为首所能形成的最小的长度相等的串小,如果小就放子串,如果不小就先放这个字符
然后确定了首位,到后面就好判了,观察这个子串是不是小于全为子串首位的,比如1001<1111,如果小于就先放子串再放这一种字母,如果大于就先放这个字母再放子串,注意从头到尾子串放一次就够了
最后注意原串为零的情况以及除去子串以外全为零的情况
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<iostream>
#include<vector>
#include<set>
#include<queue>
#include<algorithm>
#include<stack>
#include<string>
#define Max 1000010
#define INF 0x3f3f3f3f
using namespace std;
typedef long long LL;
char str[Max];
char str2[Max];
int num[15];
int main(void)
{
scanf("%s",str+1);
scanf("%s",str2+1);
int len,len2;
int rl;
len=strlen(str+1);
len2=strlen(str2+1);
if(len-1<=9)rl=len-1;
else if(len-2<=99)rl=len-2;
else if(len-3<=999)rl=len-3;
else if(len-4<=9999)rl=len-4;
else if(len-5<=99999)rl=len-5;
else if(len-6<=999999)rl=len-6;
memset(num,0,sizeof(num));
for(int i=1;i<=len;i++){
num[str[i]-'0']++;
}
while(rl){
int bit=rl%10;
num[bit]--;
rl/=10;
}
for(int i=1;i<=len2;i++){
num[str2[i]-'0']--;
}
int flag2=0;
for(int i=2;i<=len2;i++){
if(str2[i]<str2[i-1]){
flag2=1;
break;
}
else if(str2[i]>str2[i-1]){
flag2=0;
break;
}
}
int flag=1;int ff=0;
for(int i=1;i<=9;i++){
if(num[i]!=0){
ff=1;
if(str2[1]!='0'){
if(str2[1]-'0'<i){
printf("%s",str2+1);
flag=0;
}
else if(str2[1]-'0'==i){
if(flag2){
int flag3=-1;
int st=2;
num[i]--;
for(int j=0;j<=9;j++){
for(int k=1;k<=num[j];k++){
if(str2[st]-'0'<j){flag3=1;break;}
else if(str2[st]-'0'>j){flag3=0;break;}
st++;
if(st>len2)break;
}
if(st>len2||flag3!=-1)break;
}
num[i]++;
if(flag3){
printf("%s",str2+1);
flag=0;
}
else {
printf("%d",i);
num[i]--;
}
}
else {
printf("%d",i);
num[i]--;
}
}
else {
printf("%d",i);
num[i]--;
}
}
else {
printf("%d",i);
num[i]--;
}
for(int j=0;j<=9;j++){
if(flag&&flag2){
if(j>=(str2[1]-'0')){
printf("%s",str2+1);
flag=0;
}
}
for(int k=1;k<=num[j];k++){
printf("%d",j);
}
if(flag&&(!flag2)){
if(j>=(str2[1]-'0')){
printf("%s",str2+1);
flag=0;
}
}
}
break;
}
}if(!ff){
printf("%s",str2+1);
for(int i=1;i<=num[0];i++){
printf("0");
}
puts("");
}
return 0;
}