JZ DAY9总结

本文总结了JZ DAY9的比赛,包括3个编程题目:T1是关于袁绍刁难郭嘉的武力值问题,T2涉及队伍和谐排列的统计,T3是一个序列问题。分别给出了AC代码和解题思路,T1通过将k转化为二进制找到规律,T2使用状压DP解决,T3采用RMQ和分治策略。
摘要由CSDN通过智能技术生成

D A Y 9 DAY 9 DAY9

T 1 T1 T1
袁 绍 的 刁 难 袁绍的刁难

黄巾之乱后,郭嘉到了袁绍的统辖地区,结果袁绍想给我们的郭嘉大大一个下马威,且正值他招募将领的时候,于是乎,袁绍就让郭嘉大大去替他招募将领。这时候有很多很多的将领到袁绍处报到(别人家底厚,四世三公哪~~),每个将领的编号依次为1、2、3……N,第i个将领的武力值为3^(i-1)。袁绍需要我们的郭嘉大大招纳任意个将领,而郭嘉选中的将领有一个“总武力值”为各个将领的武力值之和。例如:郭嘉这一次招募了第一个将领和第三个将领,那么“总武力值”为1+9=10。袁绍想知道,他可以获得的第k大的“总武力值”是多少,请你帮助我们的郭嘉大大告诉袁绍这个第k大的“总武力值”。从文件中读入k,输出郭嘉能够获得的,第k大的“总武力值”。

Input
 数据包含n+1行,第一行读入n(n≤100)。以下n行每行包含一个k。

Output
 输出包含n行,每行输出一个对应的结果。

Sample Input
1
7

Sample Output
13

Hint
样例说明:
郭嘉能够拿到的总武力值从小到大为1、3、4、9、10、12、13……所以第7大的总武力值是13。
对于50%的输入文件,有k≤5000。
对于100%的输入文件,有k≤2^31-1。

看完题面,感觉还行,慢慢推肯定可以把规律推出来的,em。定睛一看,e题目要输出的的不是第k大吗,为什么样例是第k小,有点莫名其妙。不管了就按照样例来吧。直接手推规律,然后就发现一个很显然的规律,就是把k转换为二进制数,然后若从后往前第i位上为1,就 a n s + = 3 i − 1 ans += 3^{i - 1} ans+=3i1
AC Code:

#include <cstdio>
#define ll long long
using namespace std;

ll ans,mi[50],k,u;
int n,cnt;

int main()
{
	freopen("recruitment.in","r",stdin);
	freopen("recruitment.out","w",stdout);
	mi[0] = 1;
	for (int i = 1; i <= 32; i ++) mi[i] = mi[i - 1] * 3;
	scanf("%d",&n);
	while (n --)
	{
		scanf("%lld",&k);
		ans = 0ll;
		for (ll i = 0; (1ll << i) <= k; i ++)
			if ((1ll << i) & k) ans += mi[i];
		printf("%lld\n",ans);
	}
	fclose(stdin);
	fclose(stdout);
	return 0;
}
T 2 T2 T2
队 伍 统 计 队伍统计

现在有n个人要排成一列,编号为1->n 。但由于一些不明原因的关系,人与人之间可能存在一些矛盾关系,具体有m条矛盾关系(u,v),表示编号为u的人想要排在编号为v的人前面。要使得队伍和谐,最多不能违背k条矛盾关系(即不能有超过k条矛盾关系(u,v),满足最后v排在了u前面)。问有多少合法的排列。答案对10^9+7取模。

Input
第一行包括三个整数n,m,k。
接下来m行,每行两个整数u,v,描述一个矛盾关系(u,v)。
保证不存在两对矛盾关系(u,v),(x,y),使得u=x且v=y 。

Output
输出包括一行表示合法的排列数。

Sample Input1
4 2 1
1 3
4 2

Sample Output1
18

Sample Input2
10 12 3
2 6
6 10
1 7
4 1
6 1
2 4
7 6
1 4
10 4
10 9
5 9
8 10

Sample Output2
123120

Data Constraint
对于30%的数据,n<=10
对于60%的数据,n<=15
对应100%的数据,n,k<=20,m<=n*(n-1),保证矛盾关系不重复。

考场上对于此题的唯一想法就是这事一道DP,怎么转移,怎么设脑子一片空白。毕竟还是太弱经验不够。
考后得知原来此题正解为状压DP,设 f [ s ] [ i ] f[s][i] f[s][i]表示当状态为s时,违背了i条矛盾的方案数,那么转移方程为 f [ s ] [ i ] = f [ s ] [ i ] + f [ s − ( 1 &lt; &lt; ( j − 1 ) ) ] [ i − t ] f[s][i] = f[s][i] + f[s - (1 &lt;&lt; (j - 1))][i - t] f[s][i]=f[s][i]+f[s(1<<(j1))][it]j为当前枚举到的位置,t为违反该位置的矛盾个数。
AC Code:

#include <cstdio>
using namespace std;

const int maxn = 21;
const int mo = 1e9 + 7;
int n,m,k,g[1 << maxn],a[maxn],ans,f[1 << maxn][maxn];

void dfs(int a,int b,int c)
{
	if (c > n) return;
	g[a] = b;
	dfs(a,b,c + 1);
	dfs(a + (1 << c),b + 1,c + 1);
}

int main()
{
	freopen("count.in","r",stdin);
	freopen("count.out","w",stdout);
	scanf("%d%d%d",&n,&m,&k);
	for (int i = 1,u,v; i <= m; i ++)
	{
		scanf("%d%d",&u,&v);
		a[v] |= (1 << (u - 1));
	}
	dfs(0,0,0);
	f[0][0] = 1;
	for (int s = 0;s < (1 << n); s ++)
		for (int j = 1,t; j <= n; j ++)
			if (s & (1 << (j - 1)))
			{
				t = g[s & a[j]];
				for (int i = t; i <= k; i ++) f[s][i] = (f[s][i] + f[s - (1 << (j - 1))][i - t]) % mo;
			}
	for (int i = 0; i <= k; i ++) ans = (ans + (f[(1 << n) - 1][i])) % mo;
	printf("%d",ans);
	fclose(stdin);
	fclose(stdout);
	return 0;
}
T 3 T3 T3
序 列 问 题 序列问题

Input
首先输入n。
接下来输入n个数,描述序列 A。

Output
输出一行一个整数代表答案。

Output
输出一行一个整数代表答案。

Sample Output
66636

Data Constraint
对于30%的数据,n<=5000
对于60%的数据,n<=50000
对于100%的数据,n<=500000,0<=A[i]<=10^9

考场上一看,先用 R M Q RMQ RMQ把三十分的方法水到先,然后再去想60分的做法。
下面是30分代码:

#include <cstdio>
#define ll long long
using namespace std;

const int mo = 1e9 + 7;
const int maxn = 5e5 + 10;
int n;
ll mx[maxn][20],mi[maxn][20],ans,log[25];

ll max(ll a,ll b) {return a > b ? a : b;}

ll min(ll a,ll b) {return a < b ? a : b;}

ll f(int l,int r)
{
	int k = log[r - l + 1];
	return max(mx[l][k],mx[r - (1 << k) + 1][k]);
}

ll g(int l,int r)
{
	int k = log[r - l + 1];
	return min(mi[l][k],mi[r - (1 << k) +1][k]);
}

int main()
{
	freopen("seq.in","r",stdin);
	freopen("seq.out","w",stdout);
	scanf("%d",&n);
	log[0] = -1;
	for (int i = 1; i <= n; i ++) log[i] = log[i >> 1] + 1,scanf("%lld",&mx[i][0]),mi[i][0] = mx[i][0];
	for (int j = 1; j <= 19; j ++)
		for (int i = 1; i + (1 << j) - 1 <= n; i ++)
			mx[i][j] = max(mx[i][j - 1],mx[i + (1 << (j - 1))][j - 1]),
			mi[i][j] = min(mi[i][j - 1],mi[i + (1 << (j - 1))][j - 1]);
	for (int l = 1; l <= n; l ++)
		for (int r = l; r <= n; r ++)
			ans += ((f(l,r) % mo) * (g(l,r) % mo) % mo);
	printf("%lld",ans);	
	fclose(stdin);
	fclose(stdout);
	return 0;
}

本可以拿三十分的程序竟然意外爆零
比赛时还出现了一个小插曲,OJ太卡,竟然不小心把第三题交到第二题上了。
正解的分治暂时还不回答,日后打出来了,补上。

本项目是一个基于SSM(Spring+SpringMVC+MyBatis)框架和Vue.js前端技术的家教平台系统。该系统旨在为家教和学生提供一个便捷、高效的在线交流和预约平台,涵盖了从用户注册登录、个人信息管理、课程发布与搜索、预约与取消预约、评价反馈等一系列功能。 在后台管理方面,系统提供了管理员对用户信息、课程信息、预约记录等进行管理的功能,确保平台的正常运行和数据的准确性。通过Spring框架的依赖注入和AOP特性,实现了业务逻辑的清晰分离和高效处理;SpringMVC则负责处理前端请求和响应,提供友好的用户界面;MyBatis作为ORM框架,简化了数据库操作,提高了数据访问的效率和安全性。 前端部分采用Vue.js框架,结合Vue Router进行页面路由管理,Axios进行HTTP请求,实现了前后端分离的开发模式。Vue.js的组件化开发和响应式数据绑定特性,使得前端页面更加动态和交互性强,提升了用户体验。 数据库设计采用了MySQL,存储了用户信息、课程信息、预约记录等核心数据。通过合理的数据库表结构和索引设计,保证了系统的高效运行和数据的一致性。 该项目不仅适合计算机相关专业的毕设学生参考和学习,也适合Java学习者进行项目实战练习。通过对该项目的深入理解和二次开发,可以实现更多个性化功能,进一步提升技术水平和实践能力。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值