NYNU开学大作战之补番真开心

A:

1148: 妹妹的工资怎么算

时间限制: 1 Sec  内存限制: 128 MB
提交: 133  解决: 42
[提交][状态][讨论版][命题人:16680340122]

题目描述

《我的妹妹哪有这么可爱!》中的女主叫做高坂桐乃,高坂家的幺女,外表出众、成绩优秀、运动万能的少女,而且还兼职流行杂志的专属模特。阳光的外表下却有着特别的兴趣,是个在意周围眼光的御宅族,喜欢妹系的成人游戏和动梅露露的动画。桐乃有很多的工作,这次她有接到一个模特工作,这次一共工作n天,每天的工资为vi 有m个结算工资的日子,因为桐乃还是初中生所以她可以任意挑选m天来拿工资,但是桐乃每次不想拿太多的钱,所以她想计划使她一次性拿的钱中的最大的最小,(最后一天一定要拿工资)但是她不会分配日子,按照惯例,她找来了哥哥京介进行“人生咨询”,想让哥哥帮忙解决这个问题,哥哥也不怎么会,但是哥哥怎么会拒接妹妹的请求呢,所以他来拜托你解决这个问题。

输入

第一行 两个数 n ,m(m<=n<=100000)

第二行 n个数,vi   (vi<100000)

输出

一个数表示答案

样例输入

5 3
1 2 3 4 5

样例输出

6

提示

 


解释:1 2 3// 4// 5 //  //为拿工资

思路:

经典二分,注意不需要排序

代码:

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn = (int)1e5 + 10;
int a[maxn],n,m;
bool judge(ll mid)
{
	ll cnt = 0,k = 1;
	for (int i = 0;i < n;i ++)
	{
		if (a[i] > mid) return 0;
		cnt += a[i];
		if (cnt > mid)
		{
			k ++;
			cnt = a[i];
		}
	}
	if (k > m) return 0;
	return 1;
}
int main()
{
	ll sum = 0;
	scanf("%d %d",&n,&m);
	for (int i = 0;i < n;i ++)
	{
		scanf("%d",&a[i]);
		sum += a[i];
	}
	ll l = 0,r = sum,mid;
	while (l <= r)
	{
		mid = (l + r) >> 1;
		if (judge(mid))
			r = mid - 1;
		else
			l = mid + 1;
	}
	printf("%lld\n",l);
	return 0;
}

C:
1150: 找面码

时间限制: 1 Sec  内存限制: 128 MB
提交: 56  解决: 25
[提交][状态][讨论版][命题人:16680340122]

题目描述

超和平Busters里的面码在这个城市里迷路了,仁太特别着急,面码很害怕一个人,所以仁太想快一点到达面码的身边,现在仁太手上只有一张地图,地图上标明了m条街道,连接着n个区 每条路都会有一个交通压力,现在仁太在s点,他知道面码在t点,请你帮仁太规划一条交通压力最小的路线使他快一点到达面码的身边并且使得经过道路的拥挤度最大值最小

输入

第一行四个数字n,m,s,t。

接下来m 行 每行三个数字表示两个区和这条路的交通压力 两个区可能有多条路相连

n<=10000,m<=2n,拥挤度<=10000

 

输出

输出题目要求的拥挤度

说明: 题目保证可以从s出发到达t  且 1<=s.t<=n 

 

样例输入

3 3 1 3
1 2 2
2 3 1
1 3 4

样例输出

2

思路:

dijkstra最短路写一写

代码:

#include<bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
const int maxn = (int)1e4 +10;
typedef pair<int,int> pii;
vector<pii> G[maxn];
int n,m,s,t;
int dis[maxn];
void solve()
{
    priority_queue<pii,vector<pii>,greater<pii> > que;
    memset(dis,0x3f,sizeof(dis));
    dis[s] = 0;
    que.push(pii(0,s));
    while (!que.empty())
    {
        pii p = que.top();
        que.pop();
        int v = p.second;
        if (dis[v] < p.first) continue;
        for (int i = 0;i < G[v].size();i ++)
        {
            pii r = G[v][i];
            if (max(r.second,dis[v]) < dis[r.first])
            {
                dis[r.first] = max(r.second,dis[v]);
                que.push(pii(dis[r.first],r.first));
            }
        }
    }
    printf("%d\n",dis[t]);
}
int main()
{
    scanf("%d %d %d %d",&n,&m,&s,&t);
    int u,v,val;
    for (int i = 0;i < m;i ++)
    {
        scanf("%d %d %d",&u,&v,&val);
        G[u].push_back(pii(v,val));
        G[v].push_back(pii(u,val));
    }
    solve();
    return 0;
}

D:

1151: 轻羽飞扬

时间限制: 1 Sec  内存限制: 128 MB
提交: 137  解决: 38
[提交][状态][讨论版][命题人:16680340122]

题目描述

电视动画《轻羽飞扬》改编自滨田浩辅原作的同名漫画,作为今年的7月新番,dyl非常喜欢尤其是里面的大魔王&&主角 羽咲绫乃,我们知道绫乃小的时候特别喜欢打羽毛球,她的母亲千夏是一个非常有名的羽毛球选手曾获得女子单人羽毛球全日本综合优胜十连霸冠军,对待自己的女儿千夏有独特的训练方式,绫乃很喜欢和母亲打羽毛球,但是呢千夏每天只和绫乃打一局,一旦绫乃接不住母亲的球,千夏就让绫乃自己训练,作为绫乃的好朋友藤泽英玲奈你将如何帮助绫乃能够更多的接到母亲的羽毛球呢?

首先 我们将羽毛球场分成0-10 11个位置如图所示

 

最开始 绫乃站在5的位置,每一秒钟都会有若干个球落在若干个位置,由于绫乃刚刚进行过训练所以很累,她只能接到所处位置或者相邻位置上的球,所以绫乃最多能够接到几个球呢?

输入

输入有多组 不超过10组数据    以0结尾

每组 第一行一个数 n 表示球的数量  (n<100000)

第二行到n+1行每行两个数x,t (x代表球落下的位置,t代表第几秒) (t<100000)

输出

一个数代表 绫乃最多能够接到的球的数量

//

开始时站在5这个位置,因此在第一秒,ta只能接到4,5,6这三个位置中其中一个位置上的羽毛球。问最多可能接到多少个球?

 

样例输入

6
5 1
4 1
6 1
7 2
7 2
8 3
0

样例输出

4

提示


这个题多组输入    输入时请用while(cin>>n&&n) 以0结尾
接球时要么接自己原来位置上的球或者是移动到相邻的位置接相邻位置的球

思路:

刚开始试图爆搜bfs直接搞,然而TLE83(大哭),所以还是dp大法好

bfs(TLE):

#include<bits/stdc++.h>
using namespace std;
const int maxn = (int)1e5 + 10;
bool vis[maxn];
int dx[3] = {0,1,-1};
int n,T;
int maze[15][maxn];
struct node
{
    int t,x,s;//t时间,x位置,s当前接球个数
    friend bool operator < (node u,node v)
    {
        return u.s < v.s;
    }
};
void bfs(int r)
{
    priority_queue <node> que;
    node p;
    int ans = -1;
    p.x = r,p.t = p.s = 0;
    que.push(p);
    while (!que.empty())
    {
        node p2 = que.top();
        que.pop();
        if (p2.t == T || ((p2.x - 1 >= 0 && !maze[p2.x - 1][p2.t + 1] && (p2.x + 1 <= 10 && !maze[p2.x + 1][p2.t + 1])) && !maze[p2.x][p2.t + 1]))
        {
            ans = max(ans,p2.s);
            continue;
        }
        for (int i = 0;i < 3;i ++)
        {
            p.x = p2.x + dx[i];
            if (p.x >= 0 && p.x <= 10 && maze[p.x][p2.t + 1])
            {
                p.t = p2.t + 1;
                p.s = p2.s + maze[p.x][p.t];
                que.push(p);
            }
        }
    }
    printf("%d\n",ans == -1 ? 0 : ans);
}
int main()
{
    while (~scanf("%d",&n) && n)
    {
        memset(maze,0,sizeof(maze));
        int u,v;
        T = 0;
        for (int i = 1;i <= n;i ++)
        {
            scanf("%d %d",&u,&v);
            maze[u][v] ++;
            if (v > T)
                T = v;
        }
        bfs(5);
    }
    return 0;
}

dp解法(正解):

#include<bits/stdc++.h>
using namespace std;
const int maxn = (int)1e5 + 10;
int maze[15][maxn];
int dp[15][maxn];
int main()
{
    int n;
    while (~scanf("%d",&n) && n)
    {
        memset(maze,0,sizeof(maze));
        memset(dp,0,sizeof(dp));
        int T = -1,x,t;
        for (int i = 1;i <= n;i ++)
        {
            scanf("%d %d",&x,&t);
            if (t > T)
                T = t;
            maze[x + 1][t] ++;
        }
        for (int i = T;i >= 0;i --)
            for (int j = 1;j <= 11;j ++)
                dp[j][i] = maze[j][i] + max(dp[j + 1][i + 1],max(dp[j][i + 1],dp[j - 1][i + 1]));
        printf("%d\n",dp[6][0]);
    }
    return 0;
}

F:

1153: 木叶村最安全的地方

时间限制: 1 Sec  内存限制: 128 MB
提交: 35  解决: 11
[提交][状态][讨论版][命题人:16680340122]

题目描述

在火影忍者第200话积极且最强的救兵里面,纲手的得知30年前木叶村被埋藏了很多起爆符,玄翁想要利用30年前埋藏在木叶的起爆符来摧毁木叶。这是一件非常危险的事情,纲手立马安排人手排除这些起爆符,但是为了以防万一她决定想一个万全之策,我们把木叶村分解成一个n*m的矩阵,一共有n*m 个点。现在纲手知道每个起爆符的位置,并且每张起爆符都能炸掉它所在的行列和两个对角线的地方,现在有k张起爆符,并且给你每一张起爆符的位置(x,y)问木叶村一共有几个地方没有被攻击到,纲手会想办法吧所有的村民尽可能的往安全地带转移

输入

第一行三个正整数 n,m,K,表示木叶村的大小,k张起爆符 (n, m<=10000,  k<=500)

接下来K行,每行两个正整数x,y,表示这个起爆符被摆在了第x行,第y列,数据保证没有任何两个=起爆符会被摆在同一个格子里。

输出

一个数表示木叶村一共有几个安全的地方

样例输入

12 13 6
10 4
12 10
1 1
2 3
3 2
2 6

样例输出

25

提示

第一个样例如图片所示 紫色的点代表安全地带

思路:

暴力大法好,复杂度还不算太高,且不会爆空间(给的限制大)

代码:

#include<bits/stdc++.h>
#include<cstring>
using namespace std;
const int maxn = (int)1e4 + 2;
bool mp[maxn][maxn];
int n,m;
void sign(int x,int y)
{
    for (int i = 1;i <= n;i ++)
        mp[i][y] = 1;
    for (int i = 1;i <= m;i ++)
        mp[x][i] = 1;
    int i,j;
    i = x,j = y;
    while (i <= n && j <= m)
        mp[++i][++j] = 1;
    i = x,j = y;
    while (i >= 1 && j >= 1)
        mp[--i][--j] = 1;
    i = x,j = y;
    while (i >= 1 && j <= m)
        mp[--i][++j] = 1;
    i = x,j = y;
    while (i <= n && j >= 1)
        mp[++i][--j] = 1;
}
int main()
{
    int k;
    scanf("%d %d %d",&n,&m,&k);
    int x,y;
    while (k --)
    {
        scanf("%d %d",&x,&y);
        sign(x,y);
    }
    int ans = 0;
    for (int i = 1;i <= n;i ++)
        for (int j = 1;j <= m;j ++)
            if (!mp[i][j])
                ans ++;
    printf("%d\n",ans);
    return 0;
}

G:

祝贺我校在河南省第十一届ACM程序设计竞赛中取得1金1银4铜的成绩

问题 1154 --找食物

1154: 找食物

时间限制: 1 Sec  内存限制: 128 MB
提交: 75  解决: 24
[提交][状态][讨论版][命题人:16680340122]

题目描述

很多关于末日的故事都很残酷,但这部《少女终末旅行》却不一样。没有战争,没有为了食物的争斗,没有人在乎之前发生了什么,未来会怎么样,人类在一片温暖中缓慢的等待死亡。距离极尽繁荣与荣华的人类文明迎来末日,已经经过了漫长的岁月。人类几乎死绝,就连生物都消失的迎来末日的世界。复杂建造的都市化作宛如迷宫的废墟,无从整备的机械也渐渐停止了动作。是何时结束的呢,是从何时开始结束的呢,就连这种想法也不复存在的终末世界中,有两位少女漫无目的地持续着旅行。千户与尤莉,今天也乘着爱车Kettenkrad,在废墟当中彷徨。 在终末世界中温暖地求生的反乌托邦幻想剧,就此开幕

为了在这个荒无人烟的世界上生存下去千户和尤梨不得不解决眼前的困难那就是找食物,在这个(n*m)迷宫里两人的坐标在(x,y),两人想要得到箱子里的食物就必须要找到钥匙,现在她们两人并不知道钥匙和箱子的位置她们两人很饿所以请你给他们规划一下路线让他们两人能够尽快吃到东西。输出最少要走的步数

输入

第一行两个数 n ,m 表示 迷宫的大小(n,m<1000)

第2行到 第 n+1 行 每行m个字符,"*"代表墙壁不可走 “.”代表可走 ‘S’ 钥匙 'T'  箱子的位置

n+2行 两个数 x,y 代表两人的起始位置  (只能走上下左右四个方向)

输出

能找到食物输出最少要走的步数  不能找到输出“-1”;

样例输入

3 3
S.*
..T
***
1 2

样例输出

4

提示


S T 唯一且保证存在 S T保证不再一个格子里
没有找到钥匙之前 箱子的位置是不可走的
初始位置不可能在钥匙和箱子所在的格子

思路:

两次bfs

代码:

#include<bits/stdc++.h>
using namespace std;
#define mem(a) memset(a,0,sizeof(a))
#define inf 0x3f3f3f3f
const int maxn = 1010;
char maze[maxn][maxn];
bool vis[maxn][maxn];
int n,m,ans;
struct node 
{
	int x,y,step;
	friend bool operator < (node w,node v)
	{
		return w.step > v.step;
	}
};
int dx[4] = {1,0,0,-1};
int dy[4] = {0,-1,1,0};
int bfs(int bx,int by,int ex,int ey)
{
	mem(vis);
	priority_queue<node> que;
	vis[bx][by] = 1;
	node p;
	p.x = bx,p.y = by,p.step = 0;
	que.push(p);
	ans = inf;
	while (!que.empty())
	{
		node p2 = que.top();
		que.pop();
		if (p2.x == ex && p2.y == ey)
		{
			ans = min(p2.step,ans);
			break;
		}
		for (int i = 0;i < 4;i ++)
		{
			p.x = p2.x + dx[i],p.y = p2.y + dy[i];
			if (p.x < 0 || p.x >= n || p.y < 0 || p.y >= m || vis[p.x][p.y])
				continue;
			if (maze[p.x][p.y] == '*')
				continue;
			p.step = p2.step + 1;
			vis[p.x][p.y] = 1;
			que.push(p); 
		}
	}
	if (ans == inf) return 0;
	return ans;
}
int main()
{
	scanf("%d %d",&n,&m);
	for (int i = 0;i < n;i ++)
		scanf("%s",maze[i]);
	int x,y;
	scanf("%d %d",&x,&y);
	int tx,ty,sx,sy;
	for (int i = 0;i < n;i ++)
		for (int j = 0;j < m;j ++)
		{
			if (maze[i][j] == 'S')
				sx = i,sy = j;
			if (maze[i][j] == 'T')
				tx = i,ty = j;
		}
	int d1,d2;
	d1 = bfs(x - 1,y - 1,sx,sy);
	if (d1)
	{
		d2 = bfs(sx,sy,tx,ty);
		if (d2)
			printf("%d\n",d1 + d2);
		else
			printf("-1\n");
	}
	else
		printf("-1\n");		
	return 0;
}

H:

1155: 寻找Daring

时间限制: 2 Sec  内存限制: 128 MB
提交: 51  解决: 15
[提交][状态][讨论版][命题人:16680340122]

题目描述

他们拥有梦想。总有一天,飞向广阔天空的梦想。知晓被玻璃遮盖的这片天空有多么遥远。

遥远的未来。人类在荒废的大地上建设了移动要塞都市“种植园”,并讴歌着文明。在那当中建造的驾驶员居住设施“槲寄生”,通称“鸟笼”。孩子们就住在那里。对外面的世界一无所知。对自由的天空一无所知。他们被告知的使命,只有战斗而已。敌人是一切都被谜团覆盖的巨大生命体“叫龙”。为了对抗尚未见过的敌人,孩子们乘上被称为“Franxx”的机器人。他们坚信,乘坐其中,就是对自己存在的证明。

有一位曾被称作神童的少年。代号016。名字是广。但他现在却跌落谷底。是不被人需要的存在。如果没有乘上Franxx,就如同不存在一样。在这样的广面前,某天,一位被称作02的神秘少女出现了。她的额头,长着两根艳丽的角。

“——找到了哦,我的Daring”

那些个所谓的:“大人”为了防止孩子们的反抗,所以将广和02 分隔两地,让他们不能驾驶franxx,02知道“大人”们很狡猾,一定会把广藏在离她最远的”种植园”所以你来帮计算一下02最多要经过几个“种植园”才能找到她的“daring” (种植园是连在一起的)

输入

第一行一个数n 代表有n个“种植园”    1 ≤ n ≤ 1000000

接下来n-1行 每行两个数ai bi 表示 两个种植园可以相互连接

输出

一个数输出结果

找出距离最远的两个种植园的距离

样例输入

3
1 2
2 3

样例输出

3

思路:

树直径

代码:

#include<cstdio>
#include<algorithm>
#include<queue>
#include<vector>
#include<cstring>
#define mem(a) memset(a,0,sizeof(a))
using namespace std;
const int maxn = (int)1e6 + 10;
vector<pair<int,int> > G[maxn];
int dis[maxn],ans;
bool vis[maxn];
int m,n;

int bfs(int x)
{
	mem(vis);
	mem(dis);
	vis[x] = 1;
	queue<int> q;
	q.push(x);
	dis[x] = 0;
	int p;
	while (!q.empty())
	{
		int f = q.front();
		q.pop();
		if (ans < dis[f])
		{
			p = f;
			ans = dis[f];
		}
		pair<int,int> t;
		for (int i = 0;i < G[f].size();i ++)
		{
			t = G[f][i];
			if (!vis[t.first])
			{
				dis[t.first] = dis[f] + t.second;
				vis[t.first] = 1;
				q.push(t.first);
			}
		}
	} 
	return p;
}
int main()
{
	int x,y,z;
	char ch;
	scanf("%d",&n);
	for (int i = 0;i < n - 1;i ++)
	{
		scanf("%d %d",&x,&y);
		G[x].push_back(make_pair(y,1));
		G[y].push_back(make_pair(x,1));
	}
	ans = 0;
	int point = bfs(1);
	ans = 0;
	bfs(point);
	printf("%d\n",ans + 1);
	return 0;
}

I:

1156: 所以说张处男可以造成多少种伤害?

时间限制: 2 Sec  内存限制: 128 MB
提交: 62  解决: 22
[提交][状态][讨论版][命题人:16680340122]

题目描述

随着爷爷尸体被盗,神秘少女冯宝宝的造访,少年张楚岚的平静校园生活被彻底颠覆。急于解开爷爷和自身秘密的张楚岚和没有任何记忆“不死少女”冯宝宝开启了“异人”之旅……

一人之下这么好看的番dyl 当然不会错过啦,尤其是第二季出来时候在b站广受好评,评分高达9.5,简直是国漫精品!

我们知道张处男在罗天大醮中和小师叔对战过程中用出了非常炫酷的技能,而且这个人精于盘算,现在假设张处男有 n种技能 每种技能的伤害为ai 并且能够放bi 次请问 他能一共打出多少种不超过m的伤害呢?

输入

多组输入 每组第一行两个数 n,m (1<=n<=100) (m<=100000)  0 0结尾

第二行有2n 个数,前n个数表示 n个技能的伤害,后n个数表示每个技能放的次数  每个技能次数<=10000 技能伤害<=100000

输出

每组一行一个答案

样例输入

3 10
1 2 4 2 1 1
0 0

样例输出

8

提示


第一个样例 可以组成 1 2 3 4 5 6 7 8
0伤害不算

思路:

多重背包可行性

代码:

#include<bits/stdc++.h>
using namespace std;
const int maxn = (int)1e5 + 10;
int dp[maxn];
bool vis[maxn];
int a[105],b[105];
int main()
{
    int n,m;
    while (~scanf("%d %d",&n,&m) && (n + m))
    {
        memset(vis,0,sizeof(vis));
        for (int i = 1;i <= n;i ++)
            scanf("%d",&a[i]);
        for (int i = 1;i <= n;i ++)
            scanf("%d",&b[i]);
        vis[0] = 1;
        int ans = 0;
        for (int i = 1;i <= n;i ++)
        {
            memset(dp,0,sizeof (int) * m);
            for (int j = 1;j <= m;j ++)
            {
                if (!vis[j] && vis[j - a[i]] && dp[j - a[i]] + 1 <= b[i])
                {                   //当前伤害j没有达到过且j - a[i]达到过并且达到
                    ans ++;         //伤害j-a[i]对于当前技能的使用次数
                    vis[j] = 1;
                    dp[j] = dp[j - a[i]] + 1;
                }   //dp[j]表示达到伤害j时使用当前技能的次数
            }
        }
        printf("%d\n",ans);
    }
    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值