怎么建设网站阿里云,学历网站怎么做,二级域名是什么,无法定位wordpress内容目录文章目录BattleHeapsortA Magic LampBattle
source
如果怪兽先死#xff0c;那么英雄血量不足也没关系
反悔贪心
每次都先杀怪兽再说#xff0c;如果血量不够了#xff0c;就倒回去从怪兽打出伤害由高到低反悔#xff0c;选择抵御或者加血#xff0c;肯定哪个加的更多…
文章目录BattleHeapsortA Magic LampBattle
source
如果怪兽先死那么英雄血量不足也没关系
反悔贪心
每次都先杀怪兽再说如果血量不够了就倒回去从怪兽打出伤害由高到低反悔选择抵御或者加血肯定哪个加的更多选哪个技能
能这么做是因为英雄打出的伤害是固定的所有反悔任何一次操作的代价是一样的
如果每次英雄的伤害也在变那么就不是这么简单的了
#include queue
#include cstdio
using namespace std;
#define int long long
#define maxn 100005
priority_queue int q;
int n, x, y, h1, h2;
int a[maxn];signed main() {scanf( %lld %lld %lld %lld %lld, n, x, y, h1, h2 );for( int i 1;i n;i ) scanf( %lld, a[i] );int r h2, h h2;for( int i 1;i n;i ) {q.push( a[i] );h2 - x;h1 - a[i];r min( r, h2 );if( h2 0 ) return ! printf( Win\n%lld\n, i );while( h1 0 ) {int now q.top(); q.pop();if( y now ) h1 y, h2 x;else h1 now, h2 x;}}printf( Lose\n%lld\n, h - r );return 0;
}Heapsort
source
了解一下堆排序
题意构造一个大根堆顺序使得大根堆中交换次数最多
每次弹堆时堆顶就要进行位置调整弹出然后栈底换到栈顶
显然如果每次都是需要调整111那么就会从堆顶一直到堆底
所以构造的时候111都要放在最后面
大小为iii的堆可以从i−1i-1i−1堆推出来
堆排序是一路上每个数都和111交换往上提一层那么构造就反过来一路上所有的数往下掉一层
#include cstdio
#define maxn 50005
int n;
int a[maxn];int main() {scanf( %d, n );a[1] 1;for( int i 2;i n;i ) {int x i - 1;while( x ^ 1 )a[x] a[x 1], x 1;a[i] 1, a[1] i;}for( int i 1;i n;i )printf( %d , a[i] );return 0;
}A Magic Lamp
source
刚开始不过脑子的直接记录最远的000满足前面非零数字位的个数小于等于m\rm mm的位置
然后先把这些扔了这样前面的零全都是前导零位数上就比直接从大到小扔少
这个特殊操作完了之后再老老实实从大到小扔
但是非常好的T\rm TT飞了
//TLE
#include queue
#include cstdio
#include vector
#include cstring
#include algorithm
using namespace std;
#define maxn 1005
int n, m;
char s[maxn];
bool vis[maxn];int main() {while( ~ scanf( %s %d, s 1, m ) ) {vector int pos;priority_queue pair int, int num;n strlen( s 1 );int cnt 0, p 0;for( int i 1;i n;i )if( s[i] 0 ) {pos.push_back( i );if( cnt m ) p i;}else {cnt ;num.push( make_pair( s[i] ^ 48, i ) );}if( ! p )while( m -- ) {vis[num.top().second] 1;num.pop();}else {for( int i 1;i p;i ) {vis[i] 1;if( s[i] 0 ) continue;else m --;}while( m -- ) {while( vis[num.top().second] ) num.pop();vis[num.top().second] 1;}}bool flag 0;for( int i 1;i n;i )if( vis[i] ) vis[i] 0;else flag 1, printf( %c, s[i] );if( ! flag ) printf( 0\n );else printf( \n );}return 0;
}然后就是正解了
ststst表预处理区间内的最小值
删去m\rm mm个就是留下n−m\rm n-mn−m个数直接留下最小值
但是注意区间限制第一个留下的数最高位区间限制在[1,m1][1,\rm m1][1,m1]中选第iii个留下的数在[lst1,mi][\rm lst1,mi][lst1,mi]中选lst\rm lstlst表示上一个留下的数的位置
#include cstdio
#include cstring
#define maxn 1005
int n, m;
char s[maxn];
int t[maxn], lg[maxn], pos[maxn];
int st[maxn][11];void init() {for( int i 1;i n;i ) st[i][0] i;for( int j 1;j 11;j )for( int i 1;i ( 1 j ) - 1 n;i )if( t[st[i][j - 1]] t[st[i ( 1 j - 1 )][j - 1]] )st[i][j] st[i][j - 1];else st[i][j] st[i ( 1 j - 1 )][j - 1];
}int query( int l, int r ) {int i lg[r - l 1];if( t[st[l][i]] t[st[r - ( 1 i ) 1][i]] )return st[l][i];elsereturn st[r - ( 1 i ) 1][i];
}int main() {lg[0] -1;for( int i 1;i maxn;i ) lg[i] lg[i 1] 1;while( ~ scanf( %s %d, s 1, m ) ) {n strlen( s 1 );for( int i 1;i n;i ) t[i] s[i] ^ 48;init();int cnt 0, lst 0;for( int i 1;i n - m;i ) {lst query( lst 1, m i );pos[ cnt] t[lst];}int i;for( i 1;i cnt;i ) if( pos[i] ) break;if( i cnt 1 ) printf( 0 );for( ;i cnt;i ) printf( %d, pos[i] );printf( \n );}return 0;
}t[lst]; } int i; for( i 1;i cnt;i ) if( pos[i] ) break; if( i cnt 1 ) printf( “0” ); for( ;i cnt;i ) printf( “%d”, pos[i] ); printf( “\n” ); } return 0; }