程序員進(jìn)階之算法練習(xí)(七十二)

題目1

題目鏈接
題目大意:
給出一個(gè)字符串,由小寫字母組成褥伴;
現(xiàn)在Alice和Bob在玩游戲腥沽,輪流從字符串中移除一個(gè)子串逮走,Alice先操作;
Alice允許移除偶數(shù)長度子串今阳,Bob允許移除奇數(shù)長度子串师溅;(也允許不移除)
最終看每個(gè)人移除子串的分?jǐn)?shù)總和,字母a是1分盾舌,b是2分墓臭、、矿筝、z是26分起便;
問最終誰能贏得游戲,以及勝者領(lǐng)先的分?jǐn)?shù);

輸入:
第一行榆综,整數(shù)?? 表示t個(gè)樣例 ?? (1≤??≤5?1e4)
每個(gè)樣例一行妙痹,字符串?? (1≤|??|≤2?1e5)

輸出:
每個(gè)樣例一行,勝者和勝者領(lǐng)先的分?jǐn)?shù)鼻疮;

Examples
input
5
aba
abc
cba
n
codeforces
output
Alice 2
Alice 4
Alice 4
Bob 14
Alice 93

題目解析:
Alice先手怯伊,并且可以移除偶數(shù)字符串,那么字符串如果是偶數(shù)判沟,Alice會(huì)移除所有字符耿芹;
如果是奇數(shù),Alice只會(huì)留下1個(gè)字符串挪哄,要么是最左邊吧秕,要么是左右邊的字符,選擇一個(gè)較小值迹炼;
Bob后手砸彬,只能選擇alice剩下的字符串。

class Solution {
    static const int N = 201010;
    string str;

public:
    void solve() {
        int t;
        cin >> t;
        while (t--) {
            cin >> str;
            int sum = 0;
            for (int i = 0; i < str.length(); ++i) {
                sum += str[i] - 'a' + 1;
            }
            if (str.length() % 2) {
                int bob = min(str[0], str[str.length() - 1]) - 'a' + 1;
                int alice = sum - bob;
                cout << (alice > bob ? "Alice" : "Bob") << " " << abs(alice - bob) << endl;
            }
            else {
                cout << "Alice " << sum << endl;
            }
        }
    }
}
ac;

題目2

題目鏈接
題目大意:
給出一個(gè)字符串斯入,由小寫字母組成砂碉;
如果這個(gè)字符串的所有子串都滿足,構(gòu)成字符串的字符數(shù)相差不超過1刻两,則稱這個(gè)字符串為完美字符串增蹭,比如說:

現(xiàn)在給出一個(gè)字符串,詢問是否為完美字符串磅摹;

輸入:
第一行滋迈,整數(shù)?? 表示t個(gè)樣例 ?? (1≤??≤2?1e4)
每個(gè)樣例一行,字符串?? (1≤|??|≤2?1e5)

輸出:
每個(gè)樣例一行偏瓤,如果是完美字符串則輸出YES杀怠;如果不是完美字符串則輸出NO椰憋;

Examples
input
5
aba
abb
abc
aaaaa
abcba
codeforces
output
YES
NO
YES
YES
NO

題目解析:
根據(jù)題目的要求厅克,任意子串的字符數(shù)相差要在1以內(nèi),假設(shè)一共有k個(gè)不同字符橙依;
那么從字符串中任意截取k長度的字符串证舟,必然會(huì)由不同的字符組成,否則就會(huì)出現(xiàn)重復(fù)字符數(shù)>1窗骑,然后沒出現(xiàn)的字符數(shù)位0女责,那么就不符合題目的要求;
并且由于可以任取创译,我們在[1, k]是由k個(gè)不同的字符構(gòu)成抵知,[2, k+1]也是k個(gè)不同的字符構(gòu)成,由此可以推導(dǎo)出str[k+1] = str[1],并由此類推刷喜,完美字符串必然是abcd abcd abc 這樣的重復(fù)構(gòu)成残制;
這樣只需要檢測字符串是否滿足這個(gè)特性即可。

class Solution {
    static const int N = 201010;
    string str;

public:
    void solve() {
        int t;
        cin >> t;
        while (t--) {
            cin >> str;
            int sum = 0, v[26] = {0};
            for (int i = 0; i < str.length(); ++i) {
                int index = str[i] - 'a';
                if (!v[index]) {
                    v[index] = 1;
                    ++sum;
                }
            }
            bool ans = true;
            memset(v, 0, sizeof(v));
            for (int i = 0; i < sum; ++i) {
                int index = str[i] - 'a';
                if (!v[index]) {
                    v[index] = 1;
                }
                else {
                    ans = false;
                    break;
                }
            }
            if (ans) {
                int pos = sum;
                while (pos < str.length() && ans) {
                    for (int i = pos; i < str.length() && i < (pos + sum); ++i) {
                        if (str[i] != str[i - sum]) {
                            ans = 0;
                            break;
                        }
                    }
                    pos += sum;
                }
                if (ans) {
                    cout << "YES" << endl;
                }
            }
            if (!ans) {
                cout << "NO" << endl;
            }
        }
    }
}
ac;

題目3

題目鏈接
題目大意:
給出一個(gè)數(shù)字n掖疮,將數(shù)字n可以拆分成若干個(gè)整數(shù)之和初茶;
現(xiàn)在想知道,有多少種拆分方法浊闪,要求拆分出來的整數(shù)都是回文數(shù)恼布;
(拆分出來的數(shù)字至少有一個(gè)不同,才算不同組合)

輸入:
第一行搁宾,整數(shù)?? 表示t個(gè)樣例 ?? (1≤??≤1e4)
每個(gè)樣例一行折汞,整數(shù) ?? (1≤??≤4?1e4)

輸出:
每個(gè)樣例一行,輸出不同的組合數(shù)字盖腿;結(jié)果可以對1e9+7取模字支;

Examples
input
2
5
12
output
7
74

題目解析:
首先,把1到40000的回文數(shù)全部列出來奸忽,得到若干個(gè)回文數(shù)堕伪;
題目的要求是計(jì)算數(shù)字n拆分有多少種組合,我們只看數(shù)字1和2栗菜,就是將數(shù)字n拆成1和2的和欠雌;
這個(gè)和動(dòng)態(tài)規(guī)劃的經(jīng)典題目類似:上n個(gè)臺階,每次有1步或者2步疙筹,最后有多少走法富俄;

但是這個(gè)題目有點(diǎn)不同,就是對不同走法的判斷而咆,這里只有新增不同數(shù)字的情況霍比,才認(rèn)為是不同的;(1+2和2+1是一樣的)
那么我們將回文數(shù)數(shù)字從小到大排列暴备,然后判斷每次回文數(shù)是否可以替換已有數(shù)字即可悠瞬。
比如說:
考慮數(shù)字1,有dp[1]=1涯捻,dp[2]=1, dp[3]=1, dp[4]=1;(dp[i]表示數(shù)字i有多少總走法)
考慮數(shù)字2浅妆,有dp[1]=1,dp[2]=2, dp[3]=2, dp[4]=3障癌;對于dp[2]凌外,引入2的時(shí)候多了2=2的選擇,同時(shí)還有原來的2=1+1涛浙;對于dp[4]康辑,可以在dp[2]的基礎(chǔ)上+2(新增2種選擇4=2+2, 4=1+1+2)摄欲,也可以不使用2,保留原來的4=1+1+1+1疮薇;

按照這種思路分析蒿涎,可以得到狀態(tài)轉(zhuǎn)移方程還是dp[i]=dp[i]+dp[i-k];(k是回文數(shù))

class Solution {
    static const int N = 40100;
    static const int MOD = 1e9 + 7;
    int dp[N];
    
    bool check(int k) {
        vector<int> vec;
        while (k) {
            vec.push_back(k % 10);
            k /= 10;
        }
        for (int i = 0; i < vec.size() / 2; ++i) {
            if (vec[i] != vec[vec.size() - i - 1]) {
                return false;
            }
        }
        return true;
    }

public:
    void solve() {
        vector<int> vec;
        for (int i = 1; i < N; ++i) {
            if (check(i)) {
                vec.push_back(i);
            }
        }
        dp[0] = 1;
        
        for (int j = 0; j < vec.size(); ++j) {
            for (int i = vec[j]; i < N; ++i) {
                dp[i] = ((lld)dp[i] + dp[i - vec[j]]) % MOD;
            }
        }
         
        int t;
        cin >> t;
        while (t--) {
            int n;
            cin >> n;
            cout << dp[n] << endl;
        }
    }
}
ac;

題目4

題目鏈接
題目大意:
給出n個(gè)數(shù)字??1,??2,?,???? 惦辛,要求構(gòu)造一個(gè)長度不超過300的整數(shù)數(shù)組b劳秋,要求:
數(shù)組b中沒有重復(fù)的元素;
數(shù)組b包括了數(shù)組a的所有數(shù)字胖齐;
數(shù)組b任意兩個(gè)數(shù)字的差玻淑,其絕對值可以在數(shù)組b中找到相同數(shù)字。

輸入:
第一行是整數(shù)t呀伙,表示有t個(gè)樣例 (1≤??≤50 ).
每個(gè)樣例第一行是整數(shù)?? (2≤??≤100)补履;
第二行是n個(gè)整數(shù) ??1,??2,?,???? (?100≤????≤100)

輸出:
如果有解,先輸出YES剿另,再輸出整數(shù)k箫锤,表示有k個(gè)整數(shù); (??≤??≤300)
??1,??2,?,???? (?1e9≤????≤1e9)
如果無解則輸出NO雨女;

Examples
input
4
3
3 0 9
2
3 4
5
-7 3 13 -2 8
4
4 8 12 6

output
yes
4
6 0 3 9
yEs
5
5 3 1 2 4
NO
Yes
6
8 12 6 2 4 10

題目解析:
構(gòu)造出來的數(shù)組b中不會(huì)存在負(fù)數(shù)谚攒,證明:
假設(shè)a[i]-a[j],a[j]小于零氛堕,則必然需要一個(gè)比a[i]的數(shù)字a[k]馏臭,但是a[k]-a[j]又會(huì)產(chǎn)生更大的數(shù)字;

所以數(shù)組a中存在負(fù)數(shù)無解讼稚;
其他的情況括儒,就用1、2锐想、3帮寻、4到max來填充即可。

class Solution {
    static const int N = 200010;
public:

public:
    void solve() {
        int t;
        cin >> t;
        while (t--) {
            int n;
            cin >> n;
            int maxNum = 0, minNum = 200;
            for (int i = 1; i <= n; ++i) {
                int k;
                cin >> k;
                maxNum = max(maxNum, k);
                minNum = min(minNum, k);
            }
            if (minNum < 0) {
                cout << "NO" << endl;
            }
            else {
                cout << "YES" << endl;
                cout << maxNum + 1 << endl;
                for (int i = 0; i <= maxNum; ++i) {
                    cout << i << " ";
                }
                cout << endl;
            }
        }
    }
}
ac;

題目5

題目鏈接
題目大意:
給出n個(gè)整數(shù)的數(shù)組赠摇,從左到右可以依次選擇若干個(gè)整數(shù)固逗,要求累加和在過程中始終不能為負(fù)數(shù)。
已知初始數(shù)字和為0蝉稳,想知道最多能選擇多少個(gè)數(shù)字抒蚜。

輸入:
第一行是整數(shù) ?? (1≤??≤2000)
第二行是n個(gè)整數(shù)??1 , ??2, ... ,???? (?1e9≤????≤1e9)
輸出:
輸出能選擇的最多整數(shù)掘鄙。

Examples
input
6
4 -4 1 -3 1 -3
output
5

題目解析:
一種簡單的策略:
遇到正的就吃耘戚,遇到負(fù)的就看當(dāng)前能否吃下,能夠吃則直接吃操漠;
如果不能吃收津,則考慮是否將吃過的負(fù)數(shù)吐出來饿这,如果存在某個(gè)負(fù)數(shù)的絕對值 比這個(gè)數(shù)字的絕對值要大,則可以把原來的負(fù)數(shù)吐出來撞秋,把這個(gè)數(shù)字吃進(jìn)去长捧;

可以用優(yōu)先隊(duì)列來記錄負(fù)數(shù),復(fù)雜度O(NlogN)吻贿;

class Solution {
    static const int N = 200010;
public:
    int a[N];
    priority_queue<int, vector<int>, greater<int> > q;
public:
    void solve() {
        int t = 1;
        while (t--) {
            int n;
            cin >> n;
            while (!q.empty()) {
                q.pop();
            }
            lld sum = 0, ans = 0;
            for (int i = 0; i < n; ++i) {
                int tmp;
                scanf("%d", &tmp);
                if (sum + tmp >= 0) {
                    ++ans;
                    sum += tmp;
                    if (tmp < 0) {
                        q.push(tmp);
                    }
                }
                else {
                    int top = 0;
                    if (!q.empty()) {
                        top = q.top();
                    }
                    if (top < tmp) {
                        q.pop();
                        q.push(tmp);
                        sum = sum - top + tmp;
                    }
                }
            }
            cout << ans << endl;
            
        }
    }
}
ac;
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末串结,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子舅列,更是在濱河造成了極大的恐慌肌割,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,198評論 6 514
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件帐要,死亡現(xiàn)場離奇詭異把敞,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)榨惠,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,334評論 3 398
  • 文/潘曉璐 我一進(jìn)店門奋早,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人赠橙,你說我怎么就攤上這事耽装。” “怎么了期揪?”我有些...
    開封第一講書人閱讀 167,643評論 0 360
  • 文/不壞的土叔 我叫張陵剂邮,是天一觀的道長。 經(jīng)常有香客問我横侦,道長挥萌,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,495評論 1 296
  • 正文 為了忘掉前任枉侧,我火速辦了婚禮引瀑,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘榨馁。我一直安慰自己憨栽,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,502評論 6 397
  • 文/花漫 我一把揭開白布翼虫。 她就那樣靜靜地躺著屑柔,像睡著了一般。 火紅的嫁衣襯著肌膚如雪珍剑。 梳的紋絲不亂的頭發(fā)上掸宛,一...
    開封第一講書人閱讀 52,156評論 1 308
  • 那天,我揣著相機(jī)與錄音招拙,去河邊找鬼唧瘾。 笑死措译,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的饰序。 我是一名探鬼主播领虹,決...
    沈念sama閱讀 40,743評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼求豫!你這毒婦竟也來了塌衰?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,659評論 0 276
  • 序言:老撾萬榮一對情侶失蹤蝠嘉,失蹤者是張志新(化名)和其女友劉穎猾蒂,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體是晨,經(jīng)...
    沈念sama閱讀 46,200評論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡肚菠,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,282評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了罩缴。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蚊逢。...
    茶點(diǎn)故事閱讀 40,424評論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖箫章,靈堂內(nèi)的尸體忽然破棺而出烙荷,到底是詐尸還是另有隱情,我是刑警寧澤檬寂,帶...
    沈念sama閱讀 36,107評論 5 349
  • 正文 年R本政府宣布终抽,位于F島的核電站,受9級特大地震影響桶至,放射性物質(zhì)發(fā)生泄漏昼伴。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,789評論 3 333
  • 文/蒙蒙 一镣屹、第九天 我趴在偏房一處隱蔽的房頂上張望圃郊。 院中可真熱鬧,春花似錦女蜈、人聲如沸持舆。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,264評論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽逸寓。三九已至,卻和暖如春覆山,著一層夾襖步出監(jiān)牢的瞬間竹伸,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,390評論 1 271
  • 我被黑心中介騙來泰國打工汹买, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留佩伤,地道東北人聊倔。 一個(gè)月前我還...
    沈念sama閱讀 48,798評論 3 376
  • 正文 我出身青樓晦毙,卻偏偏與公主長得像生巡,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子见妒,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,435評論 2 359

推薦閱讀更多精彩內(nèi)容