2023.7.25结题报告
2023.7.25
T1
很简单的模拟题。
直接暴力输入,在输入第二个的时候直接用第一个减去第二个,然后除以10累加即可。
#include <bits/stdc++.h>
#define int long long
#define N 1010
using namespace std;
int n, a[N], b = 10, ans;
signed main()
{
cin >> n;
for(int i = 1; i <= n; i ++)
cin >> a[i];
for(int i = 1; i <= n; i ++)
{
int x;
cin >> x;
ans += (a[i] - x) / b;
}
cout << ans << endl;
return 0;
}
T2
考试写了个DP,用f[i][j]表示以第i个为结尾选了j个的方案数,然后转移就是从1-i-1的j-1转移过来的,复杂度\(O(n^2 k)\),60pts。
#include <bits/stdc++.h>
//#define int long long
#define N 100010
#define P 998244353
using namespace std;
int n, k, f[N][20], ans, a[N];
inline int read(){int x=0,f=1;char ch=getchar();while(!isdigit(ch)){f=ch!='-';ch=getchar();}while(isdigit(ch)){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}return f?x:-x;}
signed main()
{
// freopen("sample3.in", "r", stdin);
n = read(), k = read();
k ++;
for(int i = 1; i <= n; i ++)
a[i] = read(), f[i][1] = 1;
if(k > n) return cout<< "0" << endl, 0;
for(int i = 1; i <= n; i ++)
{
for(int j = 1; j < i; j ++)
{
if(a[j] >= a[i]) continue;
for(int o = 2; o <= k; o ++)
f[i][o] = (f[i][o] + f[j][o - 1]) % P;
}
}
for(int i = 1; i <= n; i ++)
ans = (ans + f[i][k]) % P;
cout << ans << endl;
return 0;
}
正解是开10个树状数组维护每一个值当前前面大于他的以j-1为结尾的方案有多少种,然后每次都直接查询前面有多少种方案是合法的。
#include <bits/stdc++.h>
#define lb(x) (x & (-x))
#define int long long
#define P 998244353
#define N 101000
using namespace std;
inline int read(){int x=0,f=1;char ch=getchar();while(!isdigit(ch)){f=ch!='-';ch=getchar();}while(isdigit(ch)){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}return f?x:-x;}
int n, m, a[N], t[20][N], f[N][20], ans;
inline void add(int x, int k, int v){while(x <= n)t[k][x] = (t[k][x] + v) % P, x += lb(x);}
inline int ask(int x, int k){int res = 0; while(x) res = (res + t[k][x]) % P, x -= lb(x); return res % P;}
signed main()
{
n = read(); m = read();
for(int i = 1; i <= n; i ++) a[i] = read();
for(int i = 1; i <= n; i ++)
{
f[i][1] = 1;
int up = min(i, m + 1);
for(int j = 2; j <= up; j ++)
f[i][j] = (f[i][j] + ask(a[i] - 1, j - 1) % P) % P;
for(int j = 1; j <= up; j ++)
add(a[i], j, f[i][j] % P);
}
for(int i = 1; i <= n; i ++)
ans = (ans + f[i][m + 1]) % P;
cout << (ans % P) << endl;
return 0;
}
T3
没有想到怎么才能正确划分,乱搞了一下0分。
#include <bits/stdc++.h>
#define int long long
#define N 400010
using namespace std;
inline int read(){int x=0,f=1;char ch=getchar();while(!isdigit(ch)){f=ch!='-';ch=getchar();}while(isdigit(ch)){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}return f?x:-x;}
int n, a[N], m;
signed main()
{
n = read();
for(int i = 1; i <= n; i ++)
{
a[i] = read();
// a[i] += a[i - 1];
}
m = read();
while(m --)
{
int l = read(), r = read();
int o = l - 1, res = 0, sum = 0;
while(l < r)
{
sum += a[++ l];
if(sum == 0) res ++;
}
cout << res << endl;
}
return 0;
}
20分:
直接枚举两个点的前缀和一有相同的就直接加1,到最后输出即可。
#include <bits/stdc++.h>
#define int long long
#define N 400010
using namespace std;
inline int read(){int x=0,f=1;char ch=getchar();while(!isdigit(ch)){f=ch!='-';ch=getchar();}while(isdigit(ch)){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}return f?x:-x;}
int n, m, c[N], sum[N], f[N];
set<int> s;
inline void solve(int l, int r)
{
s.clear();//清空
f[l - 1] = 0;//初值
s.insert(sum[l - 1]);//插入前缀和
for(int i = l; i <= r; i ++)
{
f[i] = f[i - 1];//从前一个转移过来
if(s.find(sum[i]) != s.end()) f[i] ++, s.clear();//有相等的就加1然后清空
s.insert(sum[i]);//插入当前点的前缀和
}
cout << f[r] << endl;//输出答案
return ;
}
signed main()
{
n = read();
for(int i = 1; i <= n; i ++)
{
c[i] = read();
sum[i] = sum[i - 1] + c[i];//前缀和
}
m = read();
for(int i = 1; i <= m; i ++)
{
int l = read(), r = read();
solve(l, r);//查询
}
return 0;
}
T4
考试的时候打了一个暴力,最坏复杂度为 \(O(n^3)\),0pts。
#include <bits/stdc++.h>
#define int long long
#define P 1000000007
#define N 100010
using namespace std;
inline int read(){int x=0,f=1;char ch=getchar();while(!isdigit(ch)){f=ch!='-';ch=getchar();}while(isdigit(ch)){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}return f?x:-x;}
int n, m, a[N], ans;
inline int js(int l, int r, int k)
{
int c1 = 0, c2 = 0;
for(int i = l; i <= k; i ++)
c1 = max(c1, a[i] - a[l - 1]);
for(int i = k + 1; i <= r; i ++)
c2 = max(c2, a[r] - a[i - 1]);
return (c1 * c2) % P;
}
signed main()
{
n = read();
for(int i = 1; i <= n; i ++)
{
a[i] = read();
a[i] += a[i - 1];
}
for(int l = 1; l <= n; l ++)
for(int r = l + 1; r <= n; r ++)
for(int i = l; i <= r; i ++)
ans = (ans + js(l, r, i)) % P;
cout << ans << endl;
return 0;
}
.
本文来自博客园,作者:北烛青澜,转载请注明原文链接:https://www.cnblogs.com/Multitree/articles/17581179.html
The heart is higher than the sky, and life is thinner than paper.
浙公网安备 33010602011771号