黑龙江农垦科技职业学院喜迎寒假多校联赛2 全题解

比赛链接:这里

OP

比赛原标题:黑龙江农垦科技职业学院喜迎寒假多校联赛2(快乐ak场)
//实际上并不快乐

A 数组截取

按字符读入之后转换为数字,比scanf快,学到了~
然后用滑窗来做//大概

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#include <bits/stdc++.h>
using namespace std;
long long a[20000007],k;
int n;
inline long long read()
{
long long x = 0;
char ch = getchar();
for( ; ch > '9' || ch < '0' ; ch = getchar());
for( ; ch >= '0' && ch <= '9' ; ch = getchar()) x = (x << 3) + (x << 1) + (ch & 15);
/* x10 %16 *///因为'0'是48
return x;
}
int main()
{
n = read() , k = read();
for(int i = 1 ; i <= n ; i ++) a[i] = read();
long long i,sum=0,m=0,l=1;
i=1;
for(i=1; i<=n; i++)
{
if(a[i]>k)
{
sum=0;
l=i+1;
}
else
{
sum+=a[i];
if(sum>k)
{
sum-=a[l];
l++;
while(sum>k&&i-l+1>=m)
{
sum-=a[l];
l++;
}
}
if(sum==k)
{
m=max(i-l+1,m);
}
}
}
if(m)
printf("%lld",m);
else printf("-1");
return 0;
}

B 群友们在排列数字

深搜吧,每一层对应0~n-1的每个数,记得恢复现场。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include <bits/stdc++.h>
using namespace std;
long long a[11]={0},n,k,sum,ten=1,cou=0,//a[i]表示第i位是否被占
b[11]={1,10,100,1000,10000,100000,1000000,10000000,100000000,1000000000};
//防止pow超时
void dfs(int num)
{
if(num==n)//收束
{
if(sum%k==0)cou++;
//printf("*%d\n",sum);
}
else
{
for(int i=0;i<n;i++)
{
if(a[i]==0)
{
a[i]=1;
sum+=b[i]*num;
dfs(num+1);
sum-=b[i]*num;//恢复现场
a[i]=0;
}
}
}
}
int main()
{
scanf("%d%d",&n,&k);
dfs(0);
if(cou)printf("%lld",cou);
else printf("-1");
return 0;
}

C gg查成绩

区间和~
第 k 位存下1~ k 的和,求[ i , j ]时输出 a[ j ] - a[ i - 1 ]就好了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <bits/stdc++.h>
using namespace std;

int main()
{
static int a[1000006]={0};
int n,m,i,j;
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++)
{
scanf("%d",&a[i]);
a[i]+=a[i-1];
}
while(m--)
{
scanf("%d%d",&i,&j);
printf("%d\n",a[j]-a[i-1]);
}
return 0;
}

D issue与lifehappy给学生分组

中心是二分
类似题可以参考:NEFU OJ-1211 卖古董NEFU OJ-1708 书的复制

注意二分的临界和取整!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <bits/stdc++.h>
using namespace std;

int main()
{
static unsigned long long a[1000006];
int n,m;
unsigned long long l=1e11,r=1e19;
scanf("%d%d",&n,&m);
//printf("%d\n",n);
for(unsigned long long int i=1;i<=n;i++)
{
scanf("%llu",&a[i]);
if(a[i]<l)l=a[i];
}
while(l<r)
{
unsigned long long mid=l+r>>1;
unsigned long long team=1,num=0;
for(unsigned long long int i=1;i<=n;i++)
{
if(num+a[i]<=mid)
num+=a[i];
else team++,num=a[i];
}
if(team<=m)r=mid;
else l=mid+1;
//printf("%u %u\n",mid,team);
}
printf("%llu",l);
return 0;
}

E 删删删越小越好

因为总位数是固定的,已知删去位数即已知剩余位数,在原数中有序找到剩余位数个 数,并使最小就好了。使其最小就是对于每一位,在可以寻找的区间内找到最小数。
注意寻找区间的范围

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include <bits/stdc++.h>
using namespace std;

int main()
{
static char a[20000007];
int n,i,j,pok=0;
i=0;
while(~scanf("%c",&a[i])&&a[i++]!='\n');
a[i-1]=0;
scanf("%d",&n);
int m=strlen(a);
n=m-n;
//printf("%d",n);
int l=0;
while(n--)
{
char ma='9'+1;
int mark=0;
for(;l+n<=m-1&&ma!='0';l++)//如果找到0,就不需要再找了,没有比0更小的了&l+n<=m-1即为可寻找区间
{
if(a[l]<ma)ma=a[l],mark=l;
}
if(a[mark]!='0')pok=1;
if(pok)
printf("%c",ma);
l=mark+1;
}
if(!pok)printf("0");
return 0;
}

F happy的异或运算

异或可以看成在二进制下进行的不进位加法。
若区间右端点为n,则必存在一m满足在有效位数上(不含前导零)m==~n(即按位取反)且m<n。因为n的最高有效位必为1,m的此位即为0,故m<n。
两数异或运算后即为111…11。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <bits/stdc++.h>
using namespace std;

int main()
{
long long g;
scanf("%lld",&g);
long long int i=1;
while(g)//注
{
g>>=1;
i++;
}
i--;
cout<<(long long)pow(2,i)-1;
return 0;
}

注:这里用for(two=1;two<g;two*=2);会超时

G Alan%%%

字符串处理,闹心~

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#include <bits/stdc++.h>
using namespace std;

int main()
{
int n,i,f,sum=0;
//char a[1003];
string a;
cin>>n;
getchar();
while(n--)
{

getline(cin,a);
int cou=0,cou1=0;
f=0;
for(i=0;a[i];i++)
{
if(a[i]==' ')continue;
if(f==1)
{
if(a[i]=='l')f++;
else f=0;
}
else if(f==2)
{
if(a[i]=='a')f++;
else f=0;
}
else if(f==3)
{
if(a[i]=='n')cou1=1,f=0;
else f=0;
}
if(a[i]=='%')cou++;
else if(a[i]=='A')f=1;
}
//printf("%d %d\n",cou,cou1);
sum+=cou*cou1;
}
cout<<sum;
return 0;
}

%%%

H&I cg写项目

结构体排序,自定义cmp~
两题代码一粘就行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include <bits/stdc++.h>
using namespace std;
struct
dataa{
char n[25],m[25],x[25],h[25];
int num;
}use[1000000];
bool cmp(dataa a,dataa b)
{
if(strlen(a.n)==strlen(b.n))
{
int s=strcmp(a.n,b.n);
if(!s)
{
return a.num<b.num;//注
}
else if(s>0)return 0;
else return 1;
}
else return strlen(a.n)<strlen(b.n);
}
int main()
{
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
use[i].num=i;
scanf("%s",use[i].n);
scanf("%s",use[i].m);
scanf("%s",use[i].x);
scanf("%s",use[i].h);
}sort(use+1,use+n+1,cmp);
for(int i=1;i<=n;i++)
{
printf("%s ",use[i].n);
printf("%s ",use[i].m);
printf("%s ",use[i].x);
printf("%s\n",use[i].h);
}
return 0;
}

注:这里写a<b会报错,因为a,b是类似于迭代器。
//我怎么会这么想…

J 比赛开始了清楚姐姐喊了一句:签到了签到了

签到了签到了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <bits/stdc++.h>
using namespace std;

int main()
{
int n,m=100000,i,j,mark;
scanf("%d",&n);
for(i=1;i<=n;i++)
{
scanf("%d",&j);
if(j<m){m=j;mark=i;}
}
printf("%d",mark);
return 0;
}

ED

还是…蛮快乐的……


黑龙江农垦科技职业学院喜迎寒假多校联赛2 全题解
https://tanyuu.github.io/2021.01-06/黑龙江农垦科技职业学院喜迎寒假多校联赛2 全题解/
作者
F Juny
发布于
2021年1月23日
许可协议