- 陈俊霖 的博客
七月Day-12总结
- @ 2025-7-26 21:35:14
A. 给我一张凳子
思路: 很简单,遍历一遍就行,不会就看代码,错了纯没开long long
题解:
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 5;
long long n, a[N], ans;
int main(){
// ios_base::sync_with_stdio(false);
// cin.tie(0);cout.tie(0);
freopen ( "step.in", "r", stdin);
freopen ( "step.out", "w" ,stdout);
cin>>n;
for (long long i = 1;i <= n; i ++)
{
cin >> a[i];
}
for (long long i = 1;i <= n; i ++)
{
if ( a[i] < a[i - 1] )
{
ans += a[i - 1] - a[i];
a[i] = a[i - 1];
}
}
cout << ans;
return 0;
}
B. 枚举是不可能枚举的
思路: 求出a到b之间的所有数,减去a到b之间的所有c的倍数和a到b之间的所有d的倍数,再加上a到b之间的所有c与d的公倍数就行了
题解:
#include <bits/stdc++.h>
using namespace std;
long long a, b, ans, c, d, i;
long long gcd(long long x,long long y){//最大公约数
return y?gcd(y,x%y):x;
}
int main()
{
freopen ("div.in","r",stdin);
freopen ("div.out","w",stdout);
cin >> a >> b >> c >> d;
long long bs = c / gcd(c, d) * d;
ans = (b - a + 1) - (b / c - ( a - 1) / c) - (b / d - (a - 1) / d) + (b / bs - (a - 1) / bs);
cout << ans;
return 0;
}
C. 起遇质数
思路: 先筛出1到1e5之间的所有质数,再用前缀和求出所有符合条件的数就行
题解:
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 5;
int q, primes[N], cnt, ans, s[N];
vector <int> st(N,1);
void get_primes(int n) {
st[0]=0,st[1]=0;
for (int i = 2; i <= n; i ++) {
if(st[i]){
for(int j = i + i;j <= n;j += i)
st[j] = 0;
}
}
for (int i = 1;i <= n; i++ )
{
s[i] = s[i - 1];
if(i % 2 == 1 && st[i] && st[(i + 1) / 2])
s[i] ++;
}
}
int main()
{
freopen ( "qy.in", "r", stdin);
freopen ( "qy.out", "w", stdout);
get_primes(100005);
cin >> q;
// for(int i = 1;i <= 60;i ++)
// {
// cout << st[i] << " ";
// }
for(int i = 1;i <= q; i ++)
{
int l, r;
cin >> l >> r;
// for(int j = l - 1;j <= r;j++) cout<<s[j]<<" ";
cout << s[r] - s[l-1] << endl;
}
return 0;
}
D. 魔法咒语
思路: 完全背包模版,改一点地方就行,详细请见下方代码
题解:
#include <bits/stdc++.h>
using namespace std;
const long long N = 10005;
long long n, dp[N], a[N], b[N], H;
int main()
{
// ios_base::sync_with_stdio(false);
// cin.tie(0);cout.tie(0);
freopen ("mana.in" , "r", stdin );
freopen ("mana.out", "w", stdout);
cin >> H >> n;
for (long long i = 1; i <= n; i ++)
{
cin >> a[i] >> b[i];
}
memset(dp, 0x3f, sizeof dp);
dp[0] = 0;
for (long long i = 1; i <= n; i ++)
{
for (long long j = 0; j <= H;j ++)
{
dp[j] = min( dp[j], dp[max(j- a[i],0*1ll) ] + b[i]);
// cout << dp[j] << ' ';
}
// cout << endl;
}
//完全背包模版如下
// for(int i = 1;i <= n ;i ++)
// {
// for(int j = v[i];j <= m;j ++)
// {
// dp[j] = max( dp[j], dp[j - v[i]] + w[i]);
// }
// }
cout << dp[H];
return 0;
}
E. 简单路径统计
思路: 先建立一个无向图,用vector,再dfs深搜整个图,找出所有路径,计数就行
题解:
#include <bits/stdc++.h>
using namespace std;
const int N = 1e6,M = 2e5 + 5;
int n, m, cnt, v[M];
vector <int> adj[M];
void dfs (int u)
{
if(cnt > N)
return;
cnt++;
for (int i = 0;i < adj[u].size(); i++)
{
int j = adj[u][i];
if(v[j]) continue;
v[j] = 1;
dfs(j);
v[j] = 0;
}
}
int main()
{
// ios_base::sync_with_stdio(false);
// cin.tie(0);cout.tie(0);
cin >> n >> m;
for(int i = 0;i < m;i ++)
{
int a, b;
cin >> a >> b;
adj[a].push_back(b);
adj[b].push_back(a);
}
v[1] = 1;
dfs (1);
cout << min (cnt, N);
return 0;
}
F. 自助餐
思路: 01背包模型,输入时间和美味度,排序时间(方便更好操作),处理前N-1道菜,在T-1时间内选择,使用标准的0-1背包DP方法。对于每道菜,我们可以考虑将它作为最后一道菜,然后在剩下的时间(即使超过T-1)内吃完它。详细如下
题解:
#include <bits/stdc++.h>
using namespace std;
const long long N = 3005;
long long n, t, dp[N], ans;
pair <long long , long long> m[N];
int main()
{
// ios_base::sync_with_stdio(false);
// cin.tie(0);cout.tie(0);
freopen ( "free.in", "r", stdin);
freopen ( "free.out", "w", stdout);
cin >> n >> t;
for(long long i = 1; i <= n;i ++)
{
cin >> m[i].first >> m[i].second ;
}
sort (m + 1, m + n + 1);
for (long long i = 1;i <= n;i ++)
{
long long a = m[i].first,b = m[i].second;
if(t - 1 >= 0)
{
ans = max(ans, dp[t - 1] + b);
}
for(long long j = t - 1;j >= a;j --)
{
dp[j] = max(dp[j], dp[j - a] + b);
}
}
ans = max(ans, dp[t - 1]);
cout << ans;
return 0;
}