P1796 汤姆斯的天堂梦
题目描述
汤姆斯生活在一个等级为 0 的星球上。那里的环境极其恶劣,每天 12 小时的工作和成堆的垃圾让人忍无可忍。他向往着等级为 N 的星球上天堂般的生活。
有一些航班将人从低等级的星球送上高一级的星球,有时需要向驾驶员支付一定金额的费用,有时却又可以得到一定的金钱。
汤姆斯预先知道了从 0 等级星球去 N 等级星球所有的航线和需要支付(或者可以得到)的金钱,他想寻找一条价格最低(甚至获得金钱最多)的航线。
输入格式
第一行一个正整数 N(N≤100),接下来的数据可分为 N 个段落,每段的第一行一个整数 Ki(Ki≤100),表示等级为 i 的星球有 Ki 个。
接下来的 Ki 行中第 j 行依次表示与等级为 i,编号为 j 的星球相连的等级为 i−1 的星球的编号和此航线需要的费用(正数表示支出,负数表示收益,费用的绝对值不超过 1000)。
每行以 0 结束,每行的航线数 ≤100。
输出格式
输出所需(或所得)费用。正数表示支出,负数表示收益。
输入输出样例
输入 #1
3 2 1 15 0 1 5 0 3 1 -5 2 10 0 1 3 0 2 40 0 2 1 1 2 5 3 -5 0 2 -19 3 -20 0
输出 #1
-1
样例解释
这题说实话,如果没这个样例解释,我差点看不懂;
一开始我是想用存图来写,因为题目的意思很明显要把我往图的方向带;但是我脑子有点转不过来
从1.1星到2.1星要10块钱,要么记录下来?
vector数组要怎么存,突然脑子就不够用了
看了他们的动态规划,斯,soga
#include<bits/stdc++.h>
using namespace std;
int n,m;
int p[105][105];
int main(){
cin>>n;
for(int i=1;i<=n;i++){
cin>>m;//第i级别有m个数据
for(int j=1;j<=m;j++){//依次表示与等级为i,编号为 j 的星球相连的等级为 i-1的星球的 编号 和此航线需要的 费用 1 15 0
p[i][j]=1005;
int k,jg;
cin>>k;
while(k!=0){
cin>>jg;
p[i][j]=min(p[i][j],p[i-1][k]+jg);
cin>>k;
}
}
}
int minn=1005;
for(int i=1;i<=m;i++){
minn=min(p[n][i],minn);
}
cout<<minn;
return 0;
}
P1806 跑步
题目描述
路人甲准备跑 n 圈来锻炼自己的身体,他准备分多次(>1)跑完,每次都跑正整数圈,然后休息下再继续跑。
为了有效地提高自己的体能,他决定每次跑的圈数都必须比上次跑的多。
可以假设他刚开始跑了 0 圈,那么请问他可以有多少种跑完这 n 圈的方案?
输入格式
一行一个整数,代表 n。
输出格式
一个整数表示跑完这 n 圈的方案数。
输入输出样例
输入 #1
212
输出 #1
995645335
这题我是有点蒙的,跑来跑去的,看了题解,直呼wc 牛逼
是自己太菜了题刷少了不能怪别人牛逼...
#include<bits/stdc++.h>
using namespace std;
long long n,sum;
long long dp[1005][1005];
int main(){
cin>>n;
for(int i=1;i<=n;i++) dp[i][i]=1;
for(int i=1;i<=n;i++){
for(int j=1;j<i;j++){
for(int k=1;k<j&&k+j<=i;k++){
dp[i][j]+=dp[i-j][k];
}
}
}
for(int i=1;i<n;i++) sum+=dp[n][i];//到达n最后需要i步 把所有的到达n的结果加起来
cout<<sum<<endl;
return 0;
}
P8742 [蓝桥杯 2021 省 AB] 砝码称重
题目描述
你有一架天平和 N 个砝码, 这 N 个砝码重量依次是W1,W2,⋯,WN 。 请你计算一共可以称出多少种不同的重量?
注意砝码可以放在天平两边。
输入格式
输入的第一行包含一个整数 N 。
第二行包含 N 个整数: W1,W2,W3,⋯,WN 。
输出格式
输出一个整数代表答案。
输入输出样例
输入 #1
3 1 4 6
输出 #1
10
【样例说明】
能称出的 10 种重量是: 1、2、3、4、5、6、7、9、10、111、2、3、4、5、6、7、9、10、11 。
1=12=6−4( 天平一边放 6, 另一边放 4)
3=4−1
4=4
5=6−1
6=6
7=1+6
9=4+6−1
10=4+6
11=1+4+6
对于这题,思考在转移方程式
对于重量j,i个砝码
那么b i,j,他可以形成
b i+1,j
b i+1,j+a[i]
b i+1,j-a[i]
三种情况
多考虑一下就行了
#include<bits/stdc++.h>
using namespace std;
int n,sum,ans;
int a[105];
int b[105][10005];
int main(){
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
sum+=a[i];//得出最大的重量
}
sort(a+1,a+n+1);
b[1][a[1]]=1;
for(int i=2;i<=n;i++){//对于这n个砝码
b[i][a[i]]=1;
for(int j=1;j<=sum;j++){
if(b[i-1][j]==1){//这个j重量之前可以测量出
b[i][j]=1;
b[i][abs(j-a[i])]=1;//三个状态,第一个是不放,第二个是减去,第三个加上;
b[i][j+a[i]]=1;
}
}
}
for(int i=1;i<=sum;i++)
{
if(b[n][i]==1)
{
ans++;
}
}
cout<<ans<<endl;
return 0;
}
P1959 遗址
题目描述
很久很久以前有一座寺庙,从上往下看寺庙的形状正好是一个正方形,由 4 个角上竖立的圆柱搭建而成。现在圆柱都倒塌了,只在地上留下圆形的痕迹,可是现在地上有很多这样的痕迹,专家说一定是最大的那个。
写一个程序,给出圆柱的坐标,找出由 4 个圆柱构成的最大的正方形,因为这就是寺庙的位置,要求计算出最大的面积。注意正方形的边不一定平行于坐标轴。
例如图有 10 根柱子,其中 (4,2),(5,2),(5,3),(4,3) 可以形成一个正方形,(1,1),(4,0),(5,3),(2,4) 也可以,后者是其中最大的,面积为 10。
输入格式
第一行包含一个N(1≤N≤3000),表示柱子的数量。
接下来 N 行,每行有两个空格隔开的整数表示柱子的坐标(坐标值在 0 到5000 之间),柱子的位置互不相同。
输出格式
如果存在正方形,输出最大的面积,否则输出 0。
输入输出样例
输入 #1
10 9 4 4 3 1 1 4 2 2 4 5 8 4 0 5 3 0 5 5 2
输出 #1
10
100% 满足:1≤N≤3000
#include<bits/stdc++.h>
using namespace std;
int n,ans;
bool c[5005][5005];
int x[3005],y[3005];
int main(){
cin>>n;
for(int i=1;i<=n;i++){
cin>>x[i]>>y[i];
c[x[i]][y[i]]=true;
}
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
int a=x[i]-x[j];
int b=y[i]-y[j];//两个点推出其它两个点
int nx=x[i]-b;
int mx=x[j]-b;
int my=y[j]+a;
int ny=y[i]+a;
if(nx<1||nx>5000||mx<1||mx>5000||ny<1||ny>5000||my<1||my>5000) continue;
if(c[nx][ny]&&c[mx][my]){
ans=max(ans,a*a+b*b);
}
}
}
cout<<ans<<endl;
return 0;
}
P8794 [蓝桥杯 2022 国 A] 环境治理
题目描述
LQ 国拥有 n 个城市,从 0 到 n−1 编号,这 n 个城市两两之间都有且仅有一条双向道路连接,这意味着任意两个城市之间都是可达的。每条道路都有一个属性 D,表示这条道路的灰尘度。当从一个城市 A 前往另一个城市 B 时,可能存在多条路线,每条路线的灰尘度定义为这条路线所经过的所有道路的灰尘度之和,LQ 国的人都很讨厌灰尘,所以他们总会优先选择灰尘度最小的路线。
LQ 国很看重居民的出行环境,他们用一个指标 P 来衡量 LQ 国的出行环境,P 定义为:
P=i=0∑n−1j=0∑n−1d(i,j)
其中 d(i,j) 表示城市 i 到城市 j 之间灰尘度最小的路线对应的灰尘度的值。
为了改善出行环境,每个城市都要有所作为,当某个城市进行道路改善时,会将与这个城市直接相连的所有道路的灰尘度都减少 1,但每条道路都有一个灰尘度的下限值 L,当灰尘度达到道路的下限值时,无论再怎么改善,道路的灰尘度也不会再减小了。
具体的计划是这样的:
第 1 天,0 号城市对与其直接相连的道路环境进行改善;
第 2 天,1 号城市对与其直接相连的道路环境进行改善;
……
第 n 天n−1 号城市对与其直接相连的道路环境进行改善;
第n+1 天,0 号城市对与其直接相连的道路环境进行改善;
第 n+2 天,1 号城市对与其直接相连的道路环境进行改善;
……
LQ 国想要使得 P 指标满足 P≤Q。请问最少要经过多少天之后,P 指标可以满足 P≤Q。如果在初始时就已经满足条件,则输出0;如果永远不可能满足,则输出 −1。
输入格式
输入的第一行包含两个整数 n,Q,用一个空格分隔,分别表示城市个数和期望达到的 P 指标。
接下来 n 行,每行包含 n 个整数,相邻两个整数之间用一个空格分隔,其中第 i 行第 j 列的值 Di,j(Di,j=Dj,i,Di,i=0) 表示城市 i 与城市 j 之间直接相连的那条道路的灰尘度。
接下来 n 行,每行包含 n 个整数,相邻两个整数之间用一个空格分隔,其中第 i 行第 j 列的值 Li,j(Li,j=Lj,i,Li,i=0) 表示城市 i 与城市 j 之间直接相连的那条道路的灰尘度的下限值。
输出格式
输出一行包含一个整数表示答案。
输入输出样例
输入 #1
3 10 0 2 4 2 0 1 4 1 0 0 2 2 2 0 0 2 0 0
输出 #1
2
说明/提示
【样例说明】
初始时的图如下所示,每条边上的数字表示这条道路的灰尘度:
此时每对顶点之间的灰尘度最小的路线对应的灰尘度为:
d(0,0)=0,d(0,1)=2,d(0,2)=3;
d(1,0)=2,d(1,1)=0,d(1,2)=1;
d(2,0)=3,d(2,1)=1,d(2,2)=0。
初始时的 P 指标为(2+3+1)×2=12,不满足P≤Q=10;
第一天,0 号城市进行道路改善,改善后的图示如下:
注意到边(0,2) 的值减小了 1,但 (0,1) 并没有减小,因为L0,1=2 ,所以(0,1) 的值不可以再减小了。此时每对顶点之间的灰尘度最小的路线对应的灰尘度为:
d(0,0)=0,d(0,1)=2,d(0,2)=3,
d(1,0)=2,d(1,1)=0,d(1,2)=1,
d(2,0)=3,d(2,1)=1,d(2,2)=0。
此时 P 仍为 12。
第二天,1 号城市进行道路改善,改善后的图示如下:
此时每对顶点之间的灰尘度最小的路线对应的灰尘度为:
d(0,0)=0,d(0,1)=2,d(0,2)=2,
d(1,0)=2,d(1,1)=0,d(1,2)=0,
d(2,0)=2,d(2,1)=0,d(2,2)=0。
此时的 P 指标为(2+2)×2=8<Q,此时已经满足条件。
所以答案是 2。
#include <iostream>
using namespace std;
int map[105][105];
int lim[105][105];
int ans = -1;
int n;
long long q;
int dist[105][105];
bool floyd(int day) {
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
dist[i][j] = max(map[i][j] - day / n - (day % n >= i + 1 ? 1 : 0), lim[i][j]);
}
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
for (int z = 0; z < n; z++) {
dist[j][z] = min(dist[j][z], dist[j][i] + dist[i][z]);
}
}
}
long long sum = 0;
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
sum += dist[i][j];
}
}
if (sum >= 0 && sum <= q) {//溢出判断 && 达标
ans = day;
return true;
}
else return false;
}
void search() {//二分
int left = -1, right =12345678;
while (left + 1 != right) {
int middle = (left + right) / 2;
if (floyd(middle)) {
right = middle;
}
else {
left = middle;
}
}
}
int main() {
cin >> n >> q;
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
cin >> map[i][j];
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
cin >> lim[i][j];
search();
cout << ans;
return 0;
}