Article Directory
- The question will not be posted, and record the thought and code of the question.
- Detailed topic link
- 1. Maze (DFS)
- 2. Grasshopper jumping (BFS)
- 3. Cube status (BFS, no)
- 4. Grid division (DFS, no)
- 5,6 code fill-in-the-blank questions (omitted)
- 7. Regular problem (DFS)
- 8. Make up the number of buns (the greatest common factor + complete backpack)
- 9. Divide chocolate (two points)
- 10. Paint area (line segment tree, no)
The question will not be posted, and record the thought and code of the question.
Detailed topic link
1. Maze (DFS)
Problem-solving ideas:
DFS judges whether each point can go out in turn. Answer: 31
Code
#include <iostream>
#include <cstring>
using namespace std;
const int N = 11;
int n = 10;
char g[N][N];
bool st[N][N];
int dx[4] = {
-1,0,1,0},dy[4] = {
0,1,0,-1};
int get(char c)
{
if(c == 'U') return 0;
else if(c == 'R') return 1;
else if(c == 'D') return 2;
else return 3;
}
bool dfs(int x,int y)
{
if(x <0 || x >= n || y < 0 || y >= n) return true;
st[x][y] = true;
int d = get(g[x][y]);
int a = x + dx[d], b = y + dy[d];
if(st[a][b]) return false;
if(dfs(a,b)) return true;
}
int main()
{
for(int i =0; i < n ;i ++ ) cin >> g[i];
int cnt = 0;
for(int i =0 ;i < n;i ++ )
for(int j = 0;j < n ; j ++ )
{
memset(st,0,sizeof st);
if(dfs(i,j)) cnt ++;
}
cout << cnt << endl;
}
// 答案:31
2. Grasshopper jumping (BFS)
Problem-solving ideas:
Answer: 20
Code
#include <iostream>
#include <queue>
#include <unordered_map>
using namespace std;
int get_0(string &s)
{
for(int i = 0; i < s.size();i ++ )
if(s[i] == '0') return i;
}
int bfs()
{
string start = "012345678";
string end = "087654321";
unordered_map<string,int> step;
int d[4] = {
1,2,-1,-2};
step[start] = 0;
queue<string> q;
q.push(start);
while(q.size())
{
string s = q.front();
q.pop();
int cnt = step[s];
if(s == end) return cnt;
int pos = get_0(s);
for(int i = 0;i < 4;i ++)
{
swap(s[pos],s[((pos + d[i]) % 9 + 9) % 9 ]) ;// C ++ 取模
if(step.count(s) == 0)
{
step[s] = cnt + 1;
q.push(s);
}
swap(s[pos],s[((pos + d[i]) % 9 + 9) % 9 ]) ;// 交换回来
}
}
}
int main()
{
cout << bfs() << endl;
return 0;
}
3. Cube status (BFS, no)
Problem-solving ideas
4. Grid division (DFS, no)
Problem-solving ideas
Attach other people's questions
5,6 code fill-in-the-blank questions (omitted)
7. Regular problem (DFS)
Problem-solving ideas
Recursive processing. I thought of the number of x in () returned by dfs, but I still can't write the specific details, and I have to learn the general technique of y.
Code
#include <iostream>
using namespace std;
int k;
string s;
int dfs() // dfs返回一个()的x
{
int res = 0;
while(k < s.size())
{
if(s[k] == '(')
{
k ++; // 跳过 (
res += dfs();
k ++; // 跳过 )
}else if(s[k] == '|')
{
k ++ ; // 跳过 |
res = max(res,dfs());
}else if(s[k] == ')') break;
else if(s[k] == 'x')
{
k ++;
res ++;
}
}
return res;
}
int main()
{
cin >> s;
cout << dfs() << endl;
return 0;
}
8. Make up the number of buns (the greatest common factor + complete backpack)
Problem-solving ideas
Find the greatest common factor d of all numbers. If d != 1, it can be shown that there are infinitely many unavailable numbers, and output INF.
Otherwise, we find it through a complete knapsack (choose k numbers from n items, combinatorial problem), and guess the upper bound of the volume to be 10000.
定理:两个互斥的数p,q凑不到的最大整数:(p-1)*(q-1)-1
(Corresponding to the number of questions that cannot be bought)
Code
#include <iostream>
using namespace std;
const int N = 10010;
int n;
bool f[110][N];
int a[110];
int gcd(int a,int b) // 求最大公因数
{
return b ? gcd(b,a % b) : a;
}
int main()
{
cin >> n;
int d = 0;
for(int i = 1;i <= n;i ++){
cin >> a[i];
d = gcd(d,a[i]);
}
if(d != 1) cout << "INF" << endl;
else
{
f[0][0] = true;
for(int i = 1;i <= n; i++)
for(int j = 0;j < N;j ++)
{
f[i][j] |= f[i-1][j];
if(j >= a[i]) f[i][j] |= f[i][j - a[i]]; // 完全背包
}
int res = 0;
for(int i = 0 ;i < N;i ++ ) {
if(!f[n][i])
res ++;
}
cout << res << endl;
}
return 0;
}
9. Divide chocolate (two points)
Problem-solving ideas
Two points. First assume that the largest side length does not match, and it is dichotomy within the range of the answer. Time complexity O(nlogn)
Code
#include <iostream>
using namespace std;
const int N = 100010;
int n,k;
int h[N],w[N];
bool check(int mid)
{
int sum = 0;
for(int i = 1;i <= n;i ++)
{
sum += (h[i] / mid) * (w[i] / mid);
}
return sum >= k;
}
int main()
{
cin >> n >> k;
int l = 1,r;
for(int i = 1;i <= n ;i ++)
{
cin >> h[i] >> w[i];
r = max(r,h[i]);
r = max(r,w[i]);
}
// 二分
while(l < r)
{
int mid = l + r + 1 >> 1;
if(check(mid)) l = mid;
else r = mid - 1;
}
cout << r << endl;
return 0;
}
10. Paint area (line segment tree, no)
Problem-solving ideas
If there is no coverage, two-dimensional difference + prefix sum can be used. Covered, if you don't know the line segment tree, you will violently cycle to deceive points. (Open the bool array space will be smaller)
Other people's problem solutions