codeforce题解在哪

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了codeforce题解在哪相关的知识,希望对你有一定的参考价值。


打开APP


nth2000
关注
Codeforce8.24-8.28做题记录 原创
2022-08-24 20:58:31

nth2000 

码龄3年

关注
Nearest Excluded Points(1900)
题意:
给定n个独特的二维坐标点,找出距离每个点最近汉明距离的不在这些n个独特二维坐标点的整数坐标二维格点。
数据范围:

题解:
没有找到对每个点在Log复杂度内的算法。
事实上,对于距离相邻的点或者说挨在一起的点可以增量更新。
首先距离最近汉明距离为1的点。
再遍历这些点的邻接顶点,一定可以加入一些距离为2的点。
以此类推。每次都可以加入新格点。
迭代到所有点都加入完毕即可。

#include <bits/stdc++.h>
#include <math.h>
using namespace std;
typedef long long ll;
const ll mod = 1e9+7;

int main()

int n;
cin >> n;
set<pair<int,int>> m;
map<pair<int,int>,int> mapp;
pair<int,int> ans[n];
for(int i = 0;i<n;i++)

int x,y; cin >> x >> y;
m.insert(x,y);
mapp[x,y]=i;

set<pair<int,int>> m_;
for(auto& p : m)

int x = p.first; int y = p.second;
if(m.find(x+1,y)==m.end())
m_.insert(x,y);ans[mapp[x,y]] = x+1,y;

else if(m.find(x-1,y)==m.end())

m_.insert(x,y);ans[mapp[x,y]] = x-1,y;

else if(m.find(x,y-1)==m.end())

m_.insert(x,y);ans[mapp[x,y]] = x,y-1;

else if(m.find(x,y+1)==m.end())

m_.insert(x,y);ans[mapp[x,y]] = x,y+1;


for(auto &p : m_) m.erase(p.first);
int dis = 1;
while(!m.empty())

set<pair<int,int>> newadd;
dis++;
for(auto &p:m_)

int x = p.first.first,y = p.first.second;
int ind= mapp[x,y];
int nx = ans[ind].first,ny = ans[ind].second;
if(m.find(x-1,y)!=m.end()) newadd.insert(x-1,y);ans[mapp[x-1,y]] = nx,ny;

if(m.find(x,y-1)!=m.end()) newadd.insert(x,y-1);ans[mapp[x,y-1]] = nx,ny;

if(m.find(x+1,y)!=m.end()) newadd.insert(x+1,y);ans[mapp[x+1,y]] = nx,ny;

if(m.find(x,y+1)!=m.end()) newadd.insert(x,y+1);ans[mapp[x,y+1]] = nx,ny;


m_.clear();
for(auto p : newadd)

m.erase(p);
m_.add(newadd);


for(int i = 0;i<n;i++) printf("%d")

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
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
反思:这道题最初想法是看距离相同距离汉明距离上是否有点,但均不能在log复杂度内求解。但注意这里有多个点,看输出看能否增量更新,相邻点间的汉明距离有何关系。

Expand the Path(1900)
题意: 给定n*n网格。你初始处于(1,1)位置,给定字符串初始s只包含D和R字符,分别表示向下和向右移动一个单位。你可以任意选择字符将其在原始位置重复任意多次。对所有结果字符串对应的路径(不能走出网格),求所有能够抵达的网格数。
注意:len(s)在1e5,n在1e8
题解:划分解空间。
如果s中第i个字符前既有D又有R,考察处理完s第i个字符时(所有解中),可能走到的网格点。显然为一个长方形。处理完s第i+1个字符后,该长方形向下或向右平移一个单位,新增范围就是该长方形的长或宽。再注意一些边界条件即s中全是D或R即可。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

int main()

int t;scanf("%d",&t);
for(int i = 0;i<t;i++)
ll n;cin>>n;
string s;cin>>s;
ll countD = 0,countR = 0;
char first = s[0];
for(int v = 0;v<s.size();v++) if(s[v]=='D') countD++; else countR++;
if(countD == 0 || countR == 0) cout<<n<<endl;
else

ll ans = n - (first=='R'?countR:countD) + 1;int v = 0;
int t1 = countR,t2 = countD;
v++;
if(first=='R') countR--;else countD--;
while(s[v]==first) v++;ans++;if(first=='R')countR--;else countD--;
if(s[v] == 'D') countD--; else countR--;
ll w = n - t1; ll h = n - t2;
ans += w*h;
ans = ans + h * countR + w * countD;
cout << ans << endl;


system("pause");
return 0;

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
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
反思:最初的想法不成熟。只考虑了处理到第一次s出现D和R时能够走到的范围,想当然地认为其能够覆盖所有,并没有考虑再处理后面可能新增的范围。为何要在每个末尾处理,是因为s中初始的D和R必须存在。

Required Length(1700)
题意: 给定两个整数n,x。每次操作选取整数x的某位将x乘以它。问将x变为n位数的最小操作次数。
题解:
实验表明计算结点数不会很多。理论证明:
乘的每一位数分解质因数都是2 , 3 , 5 , 7 2,3,5,72,3,5,7的幂次
因此中间每个结果必可以表示为
x ⋅ 2 a ⋅ 3 b ⋅ 5 c ⋅ 7 d x \cdot 2^a \cdot 3^b \cdot 5^c \cdot 7^dx⋅2
a
⋅3
b
⋅5
c
⋅7
d
的形式
由数据范围的限制,中间结果数不会很多。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod = 998244353;

ll dfs(ll x,ll n,map<ll,ll>& m)

auto it = m.find(x);
if(it!=m.end()) return it->second;
bool occ[10]; memset(occ,0,sizeof(occ));
int c = 0;
ll t = (ll)x;
while(x > 0)

occ[x%10]=true; x/=10; c++;


if((ll)c == n) m[t]=0;return 0;
ll ans = LONG_LONG_MAX;
for(ll i = 2;i<=9;i++)

ll a = dfs(t*i,n,m);
if(occ[i] && a!=LONG_LONG_MAX)
ans = min(dfs(t*i,n,m) + 1,ans);

m[t] = ans;
return ans;


int main()

ll n,x;
cin >> n >> x;
map<ll,ll> m;
ll ans = dfs(x,n,m);
if(ans == LONG_LONG_MAX) cout << -1 <<endl; else cout << ans <<endl;
system("pause");
return 0;

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
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
反思:走投无路时反思暴力做法是否可行。

Not Adding(1900 GOOD)
题意:给定n个整数组成的数组a 1 , a 2 ⋯ a n a_1,a_2 \cdots a_na
1
打开APP


nth2000
关注
Codeforce8.24-8.28做题记录 原创
2022-08-24 20:58:31

nth2000 

码龄3年

关注
Nearest Excluded Points(1900)
题意:
给定n个独特的二维坐标点,找出距离每个点最近汉明距离的不在这些n个独特二维坐标点的整数坐标二维格点。
数据范围:

题解:
没有找到对每个点在Log复杂度内的算法。
事实上,对于距离相邻的点或者说挨在一起的点可以增量更新。
首先距离最近汉明距离为1的点。
再遍历这些点的邻接顶点,一定可以加入一些距离为2的点。
以此类推。每次都可以加入新格点。
迭代到所有点都加入完毕即可。

#include <bits/stdc++.h>
#include <math.h>
using namespace std;
typedef long long ll;
const ll mod = 1e9+7;

int main()

int n;
cin >> n;
set<pair<int,int>> m;
map<pair<int,int>,int> mapp;
pair<int,int> ans[n];
for(int i = 0;i<n;i++)

int x,y; cin >> x >> y;
m.insert(x,y);
mapp[x,y]=i;

set<pair<int,int>> m_;
for(auto& p : m)

int x = p.first; int y = p.second;
if(m.find(x+1,y)==m.end())
m_.insert(x,y);ans[mapp[x,y]] = x+1,y;

else if(m.find(x-1,y)==m.end())

m_.insert(x,y);ans[mapp[x,y]] = x-1,y;

else if(m.find(x,y-1)==m.end())

m_.insert(x,y);ans[mapp[x,y]] = x,y-1;

else if(m.find(x,y+1)==m.end())

m_.insert(x,y);ans[mapp[x,y]] = x,y+1;


for(auto &p : m_) m.erase(p.first);
int dis = 1;
while(!m.empty())

set<pair<int,int>> newadd;
dis++;
for(auto &p:m_)

int x = p.first.first,y = p.first.second;
int ind= mapp[x,y];
int nx = ans[ind].first,ny = ans[ind].second;
if(m.find(x-1,y)!=m.end()) newadd.insert(x-1,y);ans[mapp[x-1,y]] = nx,ny;

if(m.find(x,y-1)!=m.end()) newadd.insert(x,y-1);ans[mapp[x,y-1]] = nx,ny;

if(m.find(x+1,y)!=m.end()) newadd.insert(x+1,y);ans[mapp[x+1,y]] = nx,ny;

if(m.find(x,y+1)!=m.end()) newadd.insert(x,y+1);ans[mapp[x,y+1]] = nx,ny;


m_.clear();
for(auto p : newadd)

m.erase(p);
m_.add(newadd);


for(int i = 0;i<n;i++) printf("%d")

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
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
反思:这道题最初想法是看距离相同距离汉明距离上是否有点,但均不能在log复杂度内求解。但注意这里有多个点,看输出看能否增量更新,相邻点间的汉明距离有何关系。

Expand the Path(1900)
题意: 给定n*n网格。你初始处于(1,1)位置,给定字符串初始s只包含D和R字符,分别表示向下和向右移动一个单位。你可以任意选择字符将其在原始位置重复任意多次。对所有结果字符串对应的路径(不能走出网格),求所有能够抵达的网格数。
注意:len(s)在1e5,n在1e8
题解:划分解空间。
如果s中第i个字符前既有D又有R,考察处理完s第i个字符时(所有解中),可能走到的网格点。显然为一个长方形。处理完s第i+1个字符后,该长方形向下或向右平移一个单位,新增范围就是该长方形的长或宽。再注意一些边界条件即s中全是D或R即可。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

int main()

int t;scanf("%d",&t);
for(int i = 0;i<t;i++)
ll n;cin>>n;
string s;cin>>s;
ll countD = 0,countR = 0;
char first = s[0];
for(int v = 0;v<s.size();v++) if(s[v]=='D') countD++; else countR++;
if(countD == 0 || countR == 0) cout<<n<<endl;
else

ll ans = n - (first=='R'?countR:countD) + 1;int v = 0;
int t1 = countR,t2 = countD;
v++;
if(first=='R') countR--;else countD--;
while(s[v]==first) v++;ans++;if(first=='R')countR--;else countD--;
if(s[v] == 'D') countD--; else countR--;
ll w = n - t1; ll h = n - t2;
ans += w*h;
ans = ans + h * countR + w * countD;
cout << ans << endl;


system("pause");
return 0;

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
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
反思:最初的想法不成熟。只考虑了处理到第一次s出现D和R时能够走到的范围,想当然地认为其能够覆盖所有,并没有考虑再处理后面可能新增的范围。为何要在每个末尾处理,是因为s中初始的D和R必须存在。

Required Length(1700)
题意: 给定两个整数n,x。每次操作选取整数x的某位将x乘以它。问将x变为n位数的最小操作次数。
题解:
实验表明计算结点数不会很多。理论证明:
乘的每一位数分解质因数都是2 , 3 , 5 , 7 2,3,5,72,3,5,7的幂次
因此中间每个结果必可以表示为
x ⋅ 2 a ⋅ 3 b ⋅ 5 c ⋅ 7 d x \cdot 2^a \cdot 3^b \cdot 5^c \cdot 7^dx⋅2
a
⋅3
b
⋅5
c
⋅7
d
的形式
由数据范围的限制,中间结果数不会很多。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod = 998244353;

ll dfs(ll x,ll n,map<ll,ll>& m)

auto it = m.find(x);
if(it!=m.end()) return it->second;
bool occ[10]; memset(occ,0,sizeof(occ));
int c = 0;
ll t = (ll)x;
while(x > 0)

occ[x%10]=true; x/=10; c++;


if((ll)c == n) m[t]=0;return 0;
ll ans = LONG_LONG_MAX;
for(ll i = 2;i<=9;i++)

ll a = dfs(t*i,n,m);
if(occ[i] && a!=LONG_LONG_MAX)
ans = min(dfs(t*i,n,m) + 1,ans);

m[t] = ans;
return ans;


int main()

ll n,x;
cin >> n >> x;
map<ll,ll> m;
ll ans = dfs(x,n,m);
if(ans == LONG_LONG_MAX) cout << -1 <<endl; else cout << ans <<endl;
system("pause");
return 0;

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
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
反思:走投无路时反思暴力做法是否可行。

Not Adding(1900 GOOD)
题意:给定n个整数组成的数组a 1 , a 2 ⋯ a n a_1,a_2 \cdots a_na
1

,a
2

⋯a
n

.(不同整数)。每次操作选取i , j i,ji,j,如果数组中不存在g c d ( a i , a j ) gcd(a_i,a_j)gcd(a
i

,a
j

)则将其加入。问最多可以执行多少次这样的操作。
数据范围:


题解:解空间中至多有1 ∼ m a x ( a ) 1 \sim max(a)1∼max(a)种可能。暴力枚举每个数看其是否可以被加入。每个数只可由原数组中是其倍数的数生成,如果这些数的gcd等于该数,则由生成过程该数必须加入。否则一定不能加入(因为这些数的gcd大于该数,后续生成的gcd都大于该数,该数一定不能存在于最终数组)。

#include <bits/stdc++.h>
using namespace std;

#define RG register int
#define LL long long
#define N 200001
typedef long long ll;
ll gcd(ll a,ll b)return b == 0?a:gcd(b,a%b);
int main()

int n; cin >> n;
ll a[n]; ll maximal = - 1;set<ll> a_;
for(int i = 0;i<n;i++)cin>>a[i];maximal = max(maximal,a[i]);
bool has[maximal+1]; memset(has,0,sizeof(has));
for(int i = 0;i<n;i++) has[a[i]]=true;
for(int i = 1;i<=maximal;i++) a_.insert(i);
for(int i = 0;i<n;i++) a_.erase(a[i]);
vector<ll> r;for(ll v : a_) r.push_back(v);
ll ans = 0;
for(ll v:r)

ll g = 0;
for(ll s = v;s<=maximal;s+=v) if(has[s]) g=gcd(s,g);
if(g==v) ans++;

cout << ans << endl;
system("pause");
return 0;

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
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
反思:看看数据范围,反思暴力是否可行(考察每一个解是否可以被加入)。

,a
参考技术A codeforce题解的步骤如下:
1、 首先登录Codeforces,然后点击上方菜单栏中的“问题集”。
2、 进入“问题集”界面,可以看到每个问题都被分成了几个部分。
3、 接下来,点击书名(也就是图中的红圈)或者书名编号。
4、 然后我们进入了话题部分,因为是国外网站,所以话题是英文的,这对刷话题的人的英语也是一个很大的考验。
参考技术B codeforce题解在哪,1、点击图片的画圈部分,也就是题目的比赛来源(如果不是在比赛中的题目,直接跳过这一步)
2、找到相应的题目,点击右边的人数
在这里插入图片描述
3、点击最左边的数字就可以查看相应的代码(中间Lang那一行显示的是用的什么语言)。

codeforces Towers 题解

Little Vasya has received a young builder’s kit. The kit consists of several wooden bars, the lengths of all of them are known. The bars can be put one on the top of the other if their lengths are the same.

Vasya wants to construct the minimal number of towers from the bars. Help Vasya to use the bars in the best way possible.

Input

The first line contains an integer N (1?≤?N?≤?1000) — the number of bars at Vasya’s disposal. The second line contains N space-separated integers li — the lengths of the bars. All the lengths are natural numbers not exceeding 1000.

Output

In one line output two numbers — the height of the largest tower and their total number. Remember that Vasya should use all the bars.

Sample test(s)
input
3
1 2 3
output
1 3
input
4
6 5 6 7
output
2 3

题意就是计算一个数组中的最大反复数和去重后的数据量。

所以本题就是数组去重知识的运用,和添加一个记录,记录最大反复数。


void Towers()
{
	unsigned n;
	cin>>n;
	int *A = new int[n];

	for (unsigned i = 0; i < n; i++)
	{
		cin>>A[i];
	}
	sort(A, A+n);
	int j = 1, h = 1, max_h = 1;
	for (unsigned i = 1; i < n; i++)
	{
		if (A[i] != A[i-1])
		{
			A[j++] = A[i];
			max_h = max(max_h, h);
			h = 1;
		}
		else h++;
	}
	max_h = max(max_h, h);
	cout<<max_h<<‘ ‘<<j;

	delete [] A;
}



以上是关于codeforce题解在哪的主要内容,如果未能解决你的问题,请参考以下文章

Codeforces Round #378 (Div. 2)题解报告

codeforces比赛后怎么看题解和答案

Codeforces Educational Codeforces Round 54 题解

Codeforces 7E - Defining Macros 题解

Codeforces Round #815 (Div. 2) 题解

codeforces比赛后怎么看题解和答案