1:消灭星星
时间限制: 1 S | 内存限制: 65536 KB
Accept: 0 | Submit: 0
反卷局局长在玩消灭星星,一大堆星星按顺序竖直放进管道里,他有m次消灭星星的机会,每次都可以消灭一段连续且颜色相同的星星,如果下面的星星被消灭了,上面的星星就会因为重力而落下,现在为了优化难度,只有两种颜色的星星,0代表红色星星,1代表黄色星星,反卷局局长想问能否在给定的次数清空所有的星星?
输入
多组案例。一个正整数T,表示案例的数量。(T<=50)
每组案例先是两个正整数n和m,分别代表星星的总数和消灭星星的机会。(n<=1e5,m<=1e5)
然后按顺序给出n个整数,A1、A2、…、An。整数值代表星星的颜色(Ai=0 或 Ai=1),星星在竖直管道里的位置根据数字出现的先后,A1在最下面,A2在A1的上面…An在最顶端。
输出
针对每组案例,如果能够在给定的机会次数以内清空完星星,输出YES,否则输出NO
每组案例输出完都要换行。
样例输入
2
5 2
0 1 1 1 0
4 2
0 1 0 1
样例输出
YES
NO
HINT
样例1:第一步消灭中间的三颗星星[0,1,1,1,0] =>[0,0],第二步消灭剩余的两颗[0,0]=>[]、
样例2:两次操作无法消灭所有的星星
来源
2021-TKK-ICPC Summer Training Camp Round #1
只要考虑有多少给’块‘与块中个数无关
即 只需考虑
0 1 10 01 101 010此类
同样说明与01次序无关
int a[100001],;
int main()
{
int t;
cin >> t;
while (t--)
{
int n, m;
cin >> n >> m;
int t,num=1;
cin >> t;
for (int i = 1; i < n; ++i)
{
int e;
cin >> e;
if (e != t)
{
num++;
t = e;
}
}
if (num / 2 + 1 > m)
cout << "NO\n";
else
cout << "YES\n";
}
return 0;
}
2
2:下馆子-3
时间限制: 1 S | 内存限制: 65536 KB
Accept: 0 | Submit: 0
每学期信息学院都会组织的下馆子活动,城城是下馆子的工作人员,城城看到勤奋的学子,特别感动,就会额外给他增加出勤次数。但罗少黑入了系统,有时候心情不好,就会随意挑选一名同学,减少这位同学的出勤次数。到最后信息学院为了找到签到次数最多的那个人,从后台按时间顺序获取了n条操作信息。请你帮他们找到最终签到次数最多的那个人,如果存在多个人,即他们的次数都为max次,请输出出勤次数最先大于等于max次的同学。
输入
只有一组案例
第一行是一个正整数 n 代表总共有 n 次操作记录。(1 <= n <= 1e5)
总共n 行,每行由name,time组成。分别代表同学的名字,和出勤次数的变化(负数是减少,正数是增加)。 ( -500<=time<=500)
保证每个名字的字符不会超过 30,输入的顺序即为签到的先后。
输出
输出最终签到次数最多的那个人,如果存在多个人,即他们的次数都为max次,请输出出勤次数最先大于等于max次的同学,最后一行不要换行
样例输入
5
xinyugiegie 1
fxw 4
xinyugiegie -1
fxw -2
xinyugiegie 2
样例输出
fxw
HINT
最后有两位同学到达2次,由于fxw的出勤次数曾经最先大于等于2次因此输出fxw
模拟
考虑多个最大值时在搭建过程中出现更大值的情况
struct li {
string name;
int d;
}list[100000];
map<string, long long>c,c1;
int main()
{
int k = 0;
string mname;
int maxn=-500000000;
int n;
cin >> n;
for (int i = 0; i < n; ++i)
{
cin >> list[i].name >> list[i].d;
c[list[i].name]+=list[i].d;
}
for (map<string, long long>::iterator it = c.begin(); it != c.end(); it++)
{
if (it->second > maxn)
{
maxn = it->second;
mname = it->first;
k = 0;
}
else if (it->second == maxn)
{
++k;
}
}
if (k == 0)
{
cout << mname ;
return 0;
}
else
for (int i = 0; i < n; ++i)
{
c1[list[i].name] += list[i].d;
if (c1[list[i].name] >= maxn)
{
cout << list[i].name;
return 0;
}
}
return 0;
}
1584:光照强度-2
时间限制: 1 S | 内存限制: 65536 KB
Accept: 3 | Submit: 48
有一个长方形的房间,可以近似地看成由a行b列的方格构成。最开始,房间里每个位置的亮度为0。
在房间里共有m盏灯,每个位置可以放多盏灯。每盏灯有一定的光照强度c,可以给房间里的每个位置提供一定的亮度,但随着距离增加,提供的亮度会相应减少。
假设灯在位置(x1,y1),其光照强度为c,那么此灯对位置(x2,y2)的亮度的贡献值为
当房间里不止一盏灯的时候,照亮效果不可以叠加,某位置的的亮度为所有灯提供的亮度的最大值。
例如下图是一个3行3列的房间,在第1行第1列有一盏光照强度为3的灯,在第3行第3列有一盏光照强度为4的灯,整个房间的明亮度分布如下。
第2行第2列的亮度由两盏灯提供,但第3行第3列的灯提供的亮度更高,因此此位置的亮度为2。
请输出整个房间的明亮程度分布。
输入
一组案例。
首先是三个正整数a、b、m,表示房间有a行b列,有m盏灯。(a<=1000,b<=1000,m<=10000)
然后是m行数据,每行数据有3个正整数x、y、c,表示某一盏灯位于第x行第y列,光照强度为c。(左上角称为第1行第1列,1<=x<=a,1<=y<=b,1<=c<=100000)
输出
针对每组案例,依次输出每一格的亮度,每两个数字之间留一个空格,每行结束后要换行。
样例输入
3 3 2
1 1 3
3 3 4
样例输出
3 2 2
2 2 3
2 3 4
因为c过大直接搜索会tle
因为光线像四个方向递减即可以逆向思维认为位置从四周接收光线
有点类似积水问题的二维版
#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
int map[1003][1003] = { 0 };
int main()
{
int a, b, m;
cin >> a>>b>>m;
for (int i = 0; i < m; ++i)
{
int x, y, c;
cin >> x >> y >> c;
map[x][y] = max(c,map[x][y]);
}
//x y
for (int i = 1; i <= a; ++i)
for (int j=1; j <= b; ++j)
map[i][j] = max(map[i][j], max(0, max(map[i-1][j ] - 1, map[i][j - 1]-1)));
//x -y
for (int i=1; i <= b; ++i)
for (int j = b; j >0; --j)
map[i][j] = max(map[i][j], max(0, max(map[i-1][j]-1,map[i][j+1]-1)));
//-x y
for (int i = a; i >0; --i)
for (int j = 1; j<=b; ++j)
map[i][j] = max(map[i][j], max(0, max(map[i+1][j]-1,map[i][j-1]-1)));
//-x -y
for (int j =b; j >0; --j)
for (int i=a; i >0; --i)
map[i][j] = max(map[i][j], max(0, max(map[i + 1][j]-1,map[i][j+1]-1)));
for (int i = 1; i <= a; ++i)
{
for (int j = 1; j < b; ++j)
cout << map[i][j] << ' ';
cout << map[i][b] << endl;
}
return 0;
}