//https://img2018.cnblogs.com/blog/1646268/201908/1646268-20190806114008215-138720377.jpg

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;
}

.

posted @ 2023-07-25 22:00  北烛青澜  阅读(1)  评论(0)    收藏  举报