昨晚真的自闭。。
C. Platforms Jumping
题意:n宽的河,m块木板,每个木板宽ci,这个人一次最远可以跳d远,问有没有可能这个人可以到达对岸(n+1处),并输出可行方案(1~n每块是水面(0),还是有第i块木板覆盖(i))。
统计木板总长数,如果木板长度加上 d * 跳的步数还是小于n,不可能到达对岸了。
否则开始贪心的放木板,这里有个值得注意的点就是,贪心贪过了最后木板出现重叠怎么办,
所有贪的时候还要注意,当前可跳过的水面总数是n-sum,贪心的同时加上这个约束条件,每次减去已跳过的水面数即可。
int main()
{
ll n, m, d;
rd(n),rd(m),rd(d);
ll c[m],sum = 0;
for(int i = 0; i < m; i++)
rd(c[i]),sum += c[i];
if(sum + (d - 1) * (m + 1) < n)
{
cout << "NO\n";
return 0;
}
cout << "YES\n";
ll z = n - sum;//空了多少水面w
int a[n] = {0};
int pos = 0;
for(ll i = 0; i < m; i++)
{
pos += min(d - 1, z);//每次贪心跳过最多可使用的空水面
for(ll j = pos; j - pos < c[i]; j++) a[j] = i + 1;
z -= min(z, d - 1);
pos += c[i];
}
for(int i = 0; i < n; i++)
cout << a[i] << ' ';
return 0;
} D. Binary String Minimizing 题意:可以交换最多k次相邻数字,问你最后能得到的字典序最小的字符串
例:
8 5 11011010 01011110对于某组交换的结果,肯定是一个0跨越一串1到达这一串1的尽量左侧,
所有考虑交换时只考虑0要和前面哪个1交换(0插到这一串1的最左侧还是插到1中间某位置)而不是挨个swap。(因为题目只有0和1,每个1都是等价的,所有0和这串1的哪个都可以直接换)
每次记录当前0之前的一串1的最左侧位置在哪里。
这种写法就比较神奇。
两种情况,可以到达最左侧。
11110 ——> 01111,新的最左侧肯定是原来的j+1
第二种情况,无法到达最左侧
11110 ——>11011,那么再之后一次也不能换了,这时候 j 在哪都无所谓了。
关键在于想到维护此刻0前一整串1的最左侧
int main ()
{
int t;rd(t);
while (t--)
{
ll n,k;rd(n),rd(k);
string str;cin>> str;
ll j = 0;
for (ll i = 0; i < n; i++)
{
if(str[i] == '0')
{
ll l = min(i - j, k);
swap(str[i], str[i - l]);
k = k - l;
j++;
}
}
cout << str << "\n";
}
} 
京公网安备 11010502036488号