C. C. Blog

Security Research, Algorithm and Data Structure

Problem

瓦斯亚和皮台亚在玩一个简单的游戏。瓦斯亚心中想一个整数x,它是1到n之间的整数。然后皮台亚尝试着猜这个数字。

皮台亚每次问一个形如这样的问题:这个x是y的倍数吗?

这个游戏的流程是这样的:首先皮台亚把所有他想问的形如上述的问题都问出来(当然他也可以不问任何问题),然后瓦斯亚针对每一个问题给出yes或no的答案。最后皮台亚根据这些问题推断出瓦斯亚心中所想的x是哪个数字。

现在皮台亚想知道他最少要问多少个问题才能猜出1到n之间的那个数字。也就是说不管x是1到n之间的哪个数字只要问那些问题就能够确定那个数字了。

样例解释:

可以问是否是2,3,4这些数字倍数的三个问题。

如果都不是,说明是1.

如果是4的倍数,说明是4.

如果是3的倍数说明是3.

否则就是2。

没有比这更少的问题数目了。

阅读全文 »

Problem

一天,欧姆诺诺姆来到了朋友家里,他发现了许多糖果。有蓝色和红色两种。他知道每颗红色糖果重Wr克,每颗蓝色糖果重Wb克。吃一颗蓝色糖果会给他带来Hb的欢乐值,吃一颗红色糖果会给他带来Hr的欢乐值。

欧姆诺姆最多只能吃C克的糖果,而且每一颗糖果不能只吃一半。现在他想通过吃蓝色和红色的糖果来获得最大的欢乐值。

样例解释:每一种糖果吃两颗即可。

阅读全文 »

Problem

给出一个字符串,求该字符串的一个子串s,s包含A-Z中的全部字母,并且s是所有符合条件的子串中最短的,输出s的长度。如果给出的字符串中并不包括A-Z中的全部字母,则输出No Solution。

阅读全文 »

Problem

给出一个长度为N的整数数组A,对于每一个数组元素,如果他后面存在大于等于该元素的数,则这两个数可以组成一对。每个元素和自己也可以组成一对。例如:{5, 3, 6, 3, 4, 2},可以组成11对,如下(数字为下标): (0,0), (0, 2), (1, 1), (1, 2), (1, 3), (1, 4), (2, 2), (3, 3), (3, 4), (4, 4), (5, 5)。其中(1, 4)是距离最大的一对,距离为3。

阅读全文 »

Problem

一个长度为N的数组A,从A中选出若干个数,使得这些数的和是N的倍数。

例如:N = 8,数组A包括:2 5 6 3 18 7 11 19,可以选2 6,因为2 + 6 = 8,是8的倍数。

阅读全文 »

Problem

用一个长度为N的整数数组A,描述山峰和山谷的高度。山峰需要满足如下条件, 0 < P < N - 1 且 A[P - 1] < A[P] > A[P + 1]。

现在要将整个山分为K段,要求每段的点数都一样,且每段中都至少存在一个山峰,问最多可以分为多少段。

阅读全文 »

A CodeForces 1238A Prime Subtraction

水题,除了差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
#include<stdio.h>
#include<set>
#include<iostream>
#define mem(ss) memset(ss,0,sizeof(ss))
#define rep(d, s, t) for(int d=s;d<=t;d++)
#define rev(d, s, t) for(int d=s;d>=t;d--)
typedef long long ll;
typedef long double ld;
typedef double db;
const ll mod = 998244353;
const int N = 1e4 + 10;
#define io_opt ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
using namespace std;
ll T,x,y;
int main(){
scanf("%lld",&T);
while(T--){
scanf("%lld%lld",&x,&y);
if(x-y==1){
printf("NO\n");
}
else{
printf("YES\n");
}
}
return 0;
}

B CodeForces 1238B Kill 'Em All

排序去重,从右向左炸。

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
#include<stdio.h>
#include<set>
#include<iostream>
#include<algorithm>
#define mem(ss) memset(ss,0,sizeof(ss))
#define rep(d, s, t) for(int d=s;d<=t;d++)
#define rev(d, s, t) for(int d=s;d>=t;d--)
typedef long long ll;
typedef long double ld;
typedef double db;
const ll mod = 998244353;
const int N = 1e4 + 10;
#define io_opt ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
using namespace std;
ll T,n,r;
ll a[100020];
ll cnt=0;
int main(){
scanf("%lld",&T);
while(T--){
cnt=0;
scanf("%lld%lld",&n,&r);
for(int i=1;i<=n;i++){
scanf("%lld",&a[i]);
}
sort(a+1,a+1+n);
n=unique(a+1,a+1+n)-(a+1);
for(int i=n;i>=1;i--){
if(a[i]-cnt*r<=0){
break;
}
cnt++;
}
printf("%lld\n",cnt);
}
return 0;
}

C CodeForces 1238C Standard Free2play

比赛想成dp了,还没补。

D CodeForces 540C Ice Cave

染色,分类讨论。

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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
#include<stdio.h>
#include<set>
#include<iostream>
#include<algorithm>
#include<cstring>
#define mem(ss) memset(ss,0,sizeof(ss))
#define rep(d, s, t) for(int d=s;d<=t;d++)
#define rev(d, s, t) for(int d=s;d>=t;d--)
typedef long long ll;
typedef long double ld;
typedef double db;
const ll mod = 1000000007;
const int N = 1e4 + 10;
int f[5][5]={{0,1},{0,-1},{1,0},{-1,0}};
#define io_opt ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
const int INF = 1e8;
using namespace std;
int n,m;
int a[520][520];
string s;
int sx,sy,tx,ty,cnt=0;
void dfs(int cx,int cy){
a[cx][cy]=cnt;
for(int i=0;i<4;i++){
int xx=cx+f[i][0],yy=cy+f[i][1];
if(xx>=1&&xx<=n&&yy>=1&&yy<=m&&a[xx][yy]==0){
dfs(xx,yy);
}
}
}
int main() {
io_opt;
cin>>n>>m;
for(int i=1;i<=n;i++){
cin>>s;
for(int j=0;j<s.size();j++){
if(s[j]=='X'){
a[i][j+1]=-1;
}
else{
a[i][j+1]=0;
}
}
}
cin>>sx>>sy>>tx>>ty;
if(sx==tx&&sy==ty){
for(int i=0;i<4;i++){
int xx=sx+f[i][0],yy=sy+f[i][1];
if(xx>=1&&xx<=n&&yy>=1&&yy<=m&&a[xx][yy]==0){
cout<<"YES\n";
return 0;
}
}
cout<<"NO\n";
return 0;
}
int k=0;
if(a[tx][ty]==-1){
k=1;
}
a[sx][sy]=a[tx][ty]=0;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if(a[i][j]==0){
cnt++;
dfs(i,j);
}
}
}

if(a[sx][sy]!=a[tx][ty]){
cout<<"NO\n";
}
else{
if(k==0){
int tmp=0;
for(int i=0;i<4;i++){
int xx=tx+f[i][0],yy=ty+f[i][1];
if(xx>=1&&xx<=n&&yy>=1&&yy<=m&&a[xx][yy]!=-1){
tmp++;
}
}
if(tmp>1){
cout<<"YES\n";
}
else{
cout<<"NO\n";
}
}
else{
cout<<"YES\n";
}
}
return 0;
}

E CodeForces 545C Woodcutters

宽度为3的dp。

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
#include<stdio.h>
#include<set>
#include<iostream>
#include<algorithm>
#include<cstring>
#define mem(ss) memset(ss,0,sizeof(ss))
#define rep(d, s, t) for(int d=s;d<=t;d++)
#define rev(d, s, t) for(int d=s;d>=t;d--)
typedef long long ll;
typedef long double ld;
typedef double db;
const ll mod = 1000000007;
const int N = 1e4 + 10;
#define io_opt ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
const int INF = 1e8;
using namespace std;
int n,a[100020];
int f[100020][4];
struct E{
int x,h;
}e[100020];
int main() {
io_opt;
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d%d",&e[i].x,&e[i].h);
}
e[0].x=-2e9-10;
e[0].h=0;
e[n+1].x=2e9+10;
e[n+1].h=0;
for(int i=1;i<=n;i++){
f[i][0]=max(f[i-1][0],max(f[i-1][1],f[i-1][2]));
if(e[i].x-e[i].h>e[i-1].x+e[i-1].h){
f[i][1]=f[i][0]+1;
}
else if(e[i].x-e[i].h>e[i-1].x){
f[i][1]=max(f[i][2],max(f[i-1][0],f[i-1][1])+1);
}
else{
f[i][1]=f[i][0];
}
if(e[i].x+e[i].h<e[i+1].x){
f[i][2]=f[i][0]+1;
}
}
printf("%d\n",max(f[n][0],max(f[n][1],f[n][2])));
return 0;
}

F CodeForces 1230A Dawid and Bags of Candies

之前组队打过,当时没注意1,3个也行,wa了好久。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include<iostream>

using namespace std;
int a[10];
int sum, tot;

int main() {
for (int i = 0; i < 4; i++) {
cin >> a[i];
sum += a[i];
}
if (a[0] + a[1] == a[2] + a[3] || a[0] + a[2] == a[1] + a[3] || a[0] + a[3] == a[1] + a[2] ||
a[0] == a[1] + a[2] + a[3] || a[1] == a[0] + a[2] + a[3] || a[2] == a[0] + a[1] + a[3] ||
a[3] == a[0] + a[1] + a[2]) {
cout << "YES\n";
} else {
cout << "NO\n";
}
return 0;
}

G CodeForces 1230B Ania and Minimizing

贪心。

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<iostream>
#include<stdio.h>
#include<algorithm>
#include<map>
#include<queue>
#include<vector>
#include<cstring>
#include<stack>

#define io_opt ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define mem(arr) memset(arr,0,sizeof(arr))
#define rep(d, s, t) for(int d=s;d<=t;d++)
#define rev(d, s, t) for(int d=s;d>=t;d--)
typedef long long ll;
typedef long double ld;
typedef double db;
const ll mod = 998244353;
using namespace std;

ll gcd(ll a, ll b) { return b == 0 ? a : gcd(b, a % b); }

inline ll read() {
ll data = 0;
char ch = 0;
while (ch < '0' || ch > '9') ch = getchar();
while (ch >= '0' && ch <= '9') data = data * 10 + ch - '0', ch = getchar();
return data;
}

const int N = 5e5 + 10;
ll n, k;
string s;

int main() {
cin >> n >> k;
cin >> s;
if (k == 0) cout << s << endl;
else if (n == 1) cout << '0'<<endl;
else {
if (s[0] != '1') s[0] = '1', --k;
for (int i = 1; i < s.size(); i++) {
if (k == 0) break;
if (s[i] != '0') {
s[i] = '0';
--k;
}
}
cout << s << endl;
}
return 0;
}

H CodeForces 1228B Filling the Grid

一开始以为那个是数量...

如果匹配,剩下的2的个数幂。

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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#include<stdio.h>
#include<set>
#include<iostream>
#include<algorithm>
#include<cstring>
#define mem(ss) memset(ss,0,sizeof(ss))
#define rep(d, s, t) for(int d=s;d<=t;d++)
#define rev(d, s, t) for(int d=s;d>=t;d--)
typedef long long ll;
typedef long double ld;
typedef double db;
const ll mod = 1000000007;
const int N = 1e4 + 10;
#define io_opt ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
const int INF = 1e8;
using namespace std;
int h,w;
int a[1020][1020];
int x,cnt;
ll lowspeed(ll a,ll b,ll p){
ll cur=a,ans=0;
while(b){
if(b&1) ans=(ans+cur)%p;
cur=(cur+cur)%p;
b>>=1;
}
return ans%p;
}
ll speed(ll a,ll b,ll p){
ll cur=a,ans=1;
while(b){
if(b&1) ans=lowspeed(ans,cur,p)%p;
cur=lowspeed(cur,cur,p)%p;
b>>=1;
}
return ans%p;
}
int main() {
memset(a,-1,sizeof(a));
scanf("%d%d",&h,&w);
for(int i=1;i<=h;i++){
scanf("%d",&x);
for(int j=1;j<=x;j++){
a[i][j]=1;
}
a[i][x+1]=0;
}
for(int i=1;i<=w;i++){
scanf("%d",&x);
for(int j=1;j<=x;j++){
if(a[j][i]==0){
printf("0\n");
return 0;
}
a[j][i]=1;
}
if(a[x+1][i]==1){
printf("0\n");
return 0;
}
a[x+1][i]=0;
}
for(int i=1;i<=h;i++){
for(int j=1;j<=w;j++){
if(a[i][j]==-1) cnt++;
}
}
ll ans=speed(2,cnt,mod);
printf("%lld\n",ans);
return 0;
}

I CodeForces 1228C Primes and Multiplication

题不难,就是麻烦,算就行。

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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
#include<stdio.h>
#include<set>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#define mem(ss) memset(ss,0,sizeof(ss))
#define rep(d, s, t) for(int d=s;d<=t;d++)
#define rev(d, s, t) for(int d=s;d>=t;d--)
typedef long long ll;
typedef long double ld;
typedef double db;
const ll mod = 1e9+7;
const int N = 1e4 + 10;
#define io_opt ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
const int INF = 1e8;
using namespace std;
ll lowspeed(ll a,ll b,ll p){
ll cur=a,ans=0;
while(b){
if(b&1) ans=(ans+cur)%p;
cur=(cur+cur)%p;
b>>=1;
}
return ans%p;
}
ll speed(ll a,ll b,ll p){
ll cur=a,ans=1;
while(b){
if(b&1) ans=lowspeed(ans,cur,p)%p;
cur=lowspeed(cur,cur,p)%p;
b>>=1;
}
return ans%p;
}
const int MAXN=4e4;
bool ipr[MAXN+20];
int cnt,pri[MAXN/5];
void prime(){//∞£ Ω…∏∑®
int N=sqrt(MAXN)+0.5,mul;
memset(ipr,true,sizeof(ipr));
ipr[1]=false;
for(int i=2;i<=N;i++){
if(ipr[i]==true){
i==2?mul=1:mul=2;
for(int j=i*i;j<=MAXN;j+=i*mul){
ipr[j]=false;
}
}
}
for(int i=2;i<=MAXN;i++){
if(ipr[i]==true){
pri[++cnt]=i;
}
}
}
ll x,n,ans=1;
int inx[40020],ct=0;
int main() {
prime();
io_opt;
cin>>x>>n;
for(int i=1;i<=cnt&&x!=1;i++){
if(x%pri[i]==0){
inx[++ct]=pri[i];
}
while(x%pri[i]==0){
x/=pri[i];
}
}
if(x!=1){
inx[++ct]=x;
}
ll tmp;
for(int i=1;i<=ct;i++){
tmp=n;
while(tmp){
tmp/=inx[i];
ans=(ans*speed(inx[i],tmp,mod))%mod;
}
}
cout<<ans<<endl;
return 0;
}

J CodeForces 1210B Marcin and Training Camp

反向拓扑,用链表mle,用short的邻接矩阵存的。后来才知道有简单结论。

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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
#include<stdio.h>
#include<set>
#include<iostream>
#include<algorithm>
#include<cstring>
#define mem(ss) memset(ss,0,sizeof(ss))
#define rep(d, s, t) for(int d=s;d<=t;d++)
#define rev(d, s, t) for(int d=s;d>=t;d--)
typedef long long ll;
typedef long double ld;
typedef double db;
const ll mod = 1000000007;
const int N = 1e4 + 10;
#define io_opt ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
const int INF = 1e8;
using namespace std;
int ag[7020];
short ae[7020][7020];
int cnt=0;
int val[7020];
ll ski[7020];
int n;
ll ans=0;
bool f[7020];
int du[7020];
int s;
void dfs(int cur){
//printf("%d\n",cur);
s--;
f[cur]=true;
ans-=val[cur];
for(int i=1;i<=n;i++){
if(ae[cur][i]){
du[i]--;
}
}
for(int i=1;i<=n;i++){
if(!f[i]&&du[i]==s){
dfs(i);
}
}
}

int main() {
io_opt;
cin>>n;
s=n-1;
for(int i=1;i<=n;i++){
cin>>ski[i];
}
for(int i=1;i<=n;i++){
cin>>val[i];
ans+=val[i];
}
for(short i=1;i<=n;i++){
for(short j=i+1;j<=n;j++){
ll tmp=ski[i]^ski[j];
if(tmp&ski[i]){
//e[++cnt]=(E){i,j,g[i]};g[i]=cnt;
//ae[++cnt]=(E){i,ag[j]};ag[j]=cnt;
ae[j][i]=1;
//printf("%d %d\n",i,j);
du[i]++;
}
if(tmp&ski[j]){
//e[++cnt]=(E){j,i,g[j]};g[j]=cnt;
//ae[++cnt]=(E){j,ag[i]};ag[i]=cnt;
ae[i][j]=1;
//printf("%d %d\n",j,i);
du[j]++;
}
}
}
//cout<<"???"<<endl;

//cout<<"???"<<endl;
//cout<<"!!!"<<du[5]<<endl;
bool fg;
do{
fg=false;
for(int i=1;i<=n;i++){
//cout<<"du"<<du[i]<<endl;
if(du[i]==s&&!f[i]){
fg=true;
dfs(i);
}
}
}while(fg);
//cout<<s<<endl;
cout<<ans<<endl;
return 0;
}

K CodeForces 1157D N Problems During K Days

L CodeForces 1157E Minimum Array

multiset,找不到就找后面一个,后面没了就找第一个。

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
52
#include<stdio.h>
#include<set>
#include<iostream>
#include<algorithm>
#include<cstring>
#define mem(ss) memset(ss,0,sizeof(ss))
#define rep(d, s, t) for(int d=s;d<=t;d++)
#define rev(d, s, t) for(int d=s;d>=t;d--)
typedef long long ll;
typedef long double ld;
typedef double db;
const ll mod = 1000000007;
const int N = 1e4 + 10;
int f[5][5]={{0,1},{0,-1},{1,0},{-1,0}};
#define io_opt ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
const int INF = 1e8;
using namespace std;
multiset<int>q;
int n;
int a[200020];
int b[200020];
int x;
int main() {
io_opt;
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
}
for(int j=1;j<=n;j++){
cin>>x;
q.insert(x);
}
for(int i=1;i<=n;i++){
int tmp=n-a[i];
auto cur=q.lower_bound(tmp);
if(cur!=q.end()&&*cur==tmp){
cout<<"0 ";
q.erase(cur);
}
else{
if(cur==q.end()){
cout<<(a[i]+*q.begin())%n<<' ';
q.erase(q.begin());
}
else{
cout<<(a[i]+*cur)%n<<' ';
q.erase(cur);
}
}
}
return 0;
}

M CodeForces 633H Fibonacci-ish II

Problem

给出三维空间上的四个点(点与点的位置均不相同),判断这4个点是否在同一个平面内(4点共线也算共面)。如果共面,输出"Yes",否则输出"No"。

阅读全文 »

Problem

一个长度为M的正整数数组A,表示从左向右的地形高度。测试一种加农炮,炮弹平行于地面从左向右飞行,高度为H,如果某处地形的高度大于等于炮弹飞行的高度H(A[i] >= H),炮弹会被挡住并落在i - 1处,则A[i - 1] + 1。如果H <= A[0],则这个炮弹无效,如果H > 所有的A[i],这个炮弹也无效。现在给定N个整数的数组B代表炮弹高度,计算出最后地形的样子。

例如:地形高度A = {1, 2, 0, 4, 3, 2, 1, 5, 7}, 炮弹高度B = {2, 8, 0, 7, 6, 5, 3, 4, 5, 6, 5},最终得到的地形高度为:{2, 2, 2, 4, 3, 3, 5, 6, 7}。

阅读全文 »

Problem

51nod近日上线了用户满意度检测工具,使用高级人工智能算法,通过用户访问时间、鼠标轨迹等特征计算用户对于网站的满意程度。

现有的统计工具只能统计某一个窗口中,用户的满意程度的均值。夹克老爷想让你为统计工具添加一个新feature,即在统计均值的同时,计算窗口中满意程度的标准差和中位数(均值需要向下取整)。

阅读全文 »