洛谷100题计划(5/100)
洛谷100题计划(5/100)
P1002 [NOIP2002 普及组] 过河卒 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
不开long long见祖宗!!!
把马的控制点都标记,其余正常转移即可
\(dp[i][j] += dp[i - 1][j] + dp[i][j - 1]\)
\(i=0||j=0\)时,只能从左边或者上边转移下来
#include<bits/stdc++.h>
using i64 = long long;
using namespace std;
typedef pair<i64, i64> PII;
i64 dp[24][24];
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int u[] = {0, 1, 2, 2, 1, -1, -2, -2, -1};
int v[] = {0, -2, -1, 1, 2, 2, 1, -1, -2};
int xb, yb, xm, ym;
cin >> xb >> yb >> xm >> ym;
vector g(24, vector<bool>(24, false));
for (int i = 0; i < 9; i ++) {
int dx = u[i] + xm;
int dy = v[i] + ym;
if (dx >= 0 && dy >= 0 && dx <= xb && dy <= yb)
g[dx][dy] = true;
}
dp[0][0] = 1;
for (int i = 0; i <= xb; i ++) {
for (int j = 0; j <= yb; j ++) {
if (g[i][j]) continue;
else if (!i) dp[i][j] += dp[i][j - 1];
else if (!j) dp[i][j] += dp[i - 1][j];
else dp[i][j] += dp[i - 1][j] + dp[i][j - 1];
}
}
cout << dp[xb][yb] << '\n';
return 0;
}
P1003 [NOIP2011 提高组] 铺地毯 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
先把所以地毯存起来,然后依次判断,啊,是判断最上面的是哪块地毯,不是被多少地毯覆盖qwq
#include<bits/stdc++.h>
using i64 = long long;
using namespace std;
typedef pair<i64, i64> PII;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n;
cin >> n;
vector<int> a(n), b(n), c(n), d(n);
for (int i = 0; i < n; i ++)
cin >> a[i] >> b[i] >> c[i] >> d[i];
int x, y;
cin >> x >> y;
int ans = 0;
for (int i = 0; i < n; i ++) {
if (x >= a[i] && y >= b[i] && x <= a[i] + c[i] && y <= b[i] + d[i])
ans = i + 1;
}
if (!ans) cout << "-1\n";
else cout << ans << '\n';
return 0;
}
P1008 [NOIP1998 普及组] 三连击 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
因为数据很小,所以我们可以直接暴力排列枚举
#include<bits/stdc++.h>
using i64 = long long;
using namespace std;
typedef pair<i64, i64> PII;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int a[] = {0,1,2,3,4,5,6,7,8,9};
do{
int num1 = 0,num2 = 0,num3 = 0;
num1 = a[1] * 100 + a[2] * 10 + a[3];
num2 = a[4] * 100 + a[5] * 10 + a[6];
num3 = a[7] * 100 + a[8] * 10 + a[9];
if(num1 * 2 == num2 && num1 * 3 == num3)
cout << num1 << ' ' << num2 << ' ' << num3 << '\n';
}while(next_permutation(a + 1, a + 1 + 9));
return 0;
}
P1028 [NOIP2001 普及组] 数的计算 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
考虑\(n\)只有\(1000\),我们可以直接dfs去找答案,但是直接跑会超时,要用记忆化搜索,即记录每个数能得到的合法序列
#include<bits/stdc++.h>
using i64 = long long;
using namespace std;
typedef pair<i64, i64> PII;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n;
cin >> n;
vector<int> a(n + 1);
auto dfs = [&](auto self,int x){
if(x == 1) return 1;
if(a[x]) return a[x];
for(int i = 1;i <= (x >> 1);i ++){
a[x] += self(self, i);
}
return ++a[x];
};
cout << dfs(dfs,n) << '\n';
return 0;
}
P1029 [NOIP2001 普及组] 最大公约数和最小公倍数问题 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
观察样例其实可以发现答案都是成对出现的,所以我们只需要去枚举一半即可,且可以发现,其实\(P,Q\)都是\(x0 \times y0\)的因子,但我们不需要去枚举他的全部因子,只需要枚举到其中一个,另外一个就可以用\(\frac{x0 \times y0}{i}\)求出来,因此只需要枚举到\(\sqrt{x0 \times y0}\)即可,另外当\(x0 = y0\)时,只有\((x0,y0)\)这一对是符合的,需要特判一下
#include<bits/stdc++.h>
using i64 = long long;
using namespace std;
typedef pair<i64, i64> PII;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int x0, y0;
cin >> x0 >> y0;
auto lcm = [](int x, int y) {
return x / gcd(x, y) * y;
};
i64 q = x0 * y0, ans = 0;
for (int i = 1; i <= sqrt(q); i ++) {
if (gcd(i, q / i) == x0 && lcm(i, q / i) == y0)
ans ++;
}
if(x0 == y0) cout << 1 << '\n';
else cout << ans * 2 << '\n';
return 0;
}