表示沒看懂演算法3
【問題描述】
**有壓迫,**就有反抗。
mored的寵物在法庭的幫助下終於反抗了。作為乙隻聰明的寵物,他打算把魔法使mored的魔法書盜去,奪取mored的魔法能力。但mored怎麼會讓自己的魔法書輕易地被盜取?mored在魔法書上設定了乙個密碼鎖,密碼鎖上有乙個問題。
施以斯臥鋪魔法吧,你有m次機會,如此將得完美密碼。
然後是一串小寫字母串。
mored的寵物斯臥鋪魔法就是施法時的字串其中相鄰兩位交換。
而mored對於完美密碼的定義自然是最小字典序了。
請幫助mored的寵物,想出密碼吧。
【輸入格式】
第一行乙個整數m,表示操作次數。
第二行一串小寫字母組成的字串s,如題目所示。
【輸出格式】
輸出完美密碼。
【輸入樣例】
3dcba
【輸出樣例】
adcb
【資料範圍】
對於30%的資料|s|≤10
對於60%的資料|s|≤3,000
對於100%的資料8≤|s|≤100,000 m≤(|s|-8)^2+2
【後記】
寵物最終戰勝了mored,和自己的寵物快樂地生活著。
【樣例解釋】
先對第3,4兩位施法,字串變成dcab,然後對第2,3兩位施法,字串變成dacb,最後對第1,2兩位施法,字串變成adcb。 題解
先說說我的逗比做法
貪心,字典序要滿足前面的盡量小,從前往後依次確定每一位,若當前處理到x位
則應該從x到x+k位中選最小的交換上來
這樣複雜度是n^2,考慮用資料結構優化
由於我選擇了線段樹,所以走上了不歸路,線段樹查詢區間最值是基本操作,但是還要在區間內刪除乙個數,刪除後下次確定i到i+k位就變得有些棘手了,因為並不能確定i+k位到底在什麼位置,唯一我能想到的辦法是使得線段樹支援求區間剩下的數的個數,通過二分來尋找右邊界,這樣複雜度變為n(logn)^2。。。
#include#include#include#include#include#include#define inf 1000000000
#define ll long long
using namespace std;
ll read()
while(ch>='0'&&ch<='9')
return x*f;
}char ch[100005];
ll k;
int n,a[100005];
struct datat[400005];
void update(int k)
void build(int k,int l,int r)
int mid=(l+r)>>1;
build(k<<1,l,mid);
build(k<<1|1,mid+1,r);
update(k);
}void modify(int k,int pos,int val)
int mid=(l+r)>>1;
if(pos<=mid)
modify(k<<1,pos,val);
else modify(k<<1|1,pos,val);
update(k);
}int query(int k,int x,int y)
}int getsum(int k,int x,int y)
int find(int x,ll val)
return tmp;
}bool solve(int x)
int lim=find(x,k);
int tmp=query(1,x+1,lim);
if(t[tmp].val>=now)
printf("%c",t[tmp].val+'a');
k-=getsum(1,x,t[tmp].mn)-1;
modify(1,t[tmp].mn,inf);
return 1;
}int main()
{ k=read();
scanf("%s",ch+1);
n=strlen(ch+1);
for(int i=1;i<=n;i++)a[i]=ch[i]-'a';
build(1,1,n);
for(int i=1;i<=n;i++)
modify(1,i,a[i]);
for(int i=1;i
如果這樣想似乎用splay應該是正確選擇?
順便貼下正解
【題目模型】
給出初始字串和運算元,要求在運算元範圍內僅使用每次交換其中相鄰兩位的操作使得字串字典序盡量小。
【演算法一】
深度優先搜尋:每次列舉交換的位置,時間複雜度o(n^m)。期望得分30%
【演算法二】
對於此類問題可以使用貪心思想:由於題目要求字典序,可以貪心地從前到後確定每一位的字母。字母肯定是從小到大地列舉,操作距離內的列舉字母的話肯定會貪心地把這個字母換入目標位置。而選擇列舉的字母就是貪心地選擇盡量前的字母。證明略。
時間複雜度為o(n^2),空間複雜度為o(n)。期望得分60%
【演算法三】
演算法二可以進行優化。
演算法主要耗時在尋找每個字母目前最前是哪乙個,可以用鍊錶維護。另外目前需要的運算元可以就等於目標字母所在位置之前有多少個剩餘的沒有用的字母,可以用樹狀陣列維護。
時間複雜度為o(nlogn),空間複雜度為o(n)。期望得分100%
【驚喜】
無視運算元可以騙50%哦,再結合暴力有70%.結合演算法二有80%。大家要相信資料是很水的。比賽時有題目不會做,也沒有時間想,不妨考慮騙分吧。僅供參考。
noip模擬賽 密碼
yjc把核彈發射密碼忘掉了 其實是密碼被加密了,但是yjc不會解密。密碼由n個數字組成,第i個數字被加密成了如下形式 第k小的滿足 2 l p 1 且p為質數的p。yjc希望你能幫他算出密碼是多少。輸入格式 第一行包含乙個整數n,表示密碼中的數字個數。接下來n行每行兩個整數l和k,表示乙個數字的加密...
NOIP模擬賽 老師
題目描述 一座有n層的教學樓裡有一些學生,第i 0 i n 層有studentsi個學生。你被給定了乙個數k,如果第i層有x個學生,那麼這一層需要 x k 個老師。你可以調整每個學生的樓層,但是每個學生至多只能調整一層,就是說第i層的學生只能去第i 1層 如果有的話 第i層 第i 1層 如果i 1 ...
NOIP模擬賽 分錢
題目描述 兩個人在街上撿到了一些錢,這些錢共有n張,他們等了很久也沒有等來失主,於是決定把錢平分。但錢可能無法平分。他們先把能夠平分的錢盡量先平分了,使得剩下不能平分的錢盡量少。這些不能平分的錢怎麼辦呢他?他們決定拿去賭場裡面賭一把。他們運氣太好了,那些不能平分的錢變成了雙倍,於是他們就把那個錢分了...