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

正文

題目1

題目鏈接
題目大意:
有n個(gè)糖果衣盾,分給兩個(gè)人A和B,要求:
兩個(gè)人都有分配到糖果;
糖果不能拆分,必須全部分分完;
A的糖果數(shù)量比B的要多遇骑;

問(wèn),最終有多少種分配方案揖曾。

輸入:
第一行落萎,整數(shù)??表示有t個(gè)樣例數(shù)量 (1≤??≤1000)
接下來(lái)每個(gè)樣例一行,整數(shù)?? (1≤??≤2?1e9)

輸出:
每個(gè)樣例一行炭剪,輸出存在分配方案练链,不存在則輸出0;

Examples
input
6
7
1
2
3
2000000000
763243547
output
3
0
0
1
999999999
381621773

樣例解釋?zhuān)?br> 樣例1:
7個(gè)糖果念祭,有下面3個(gè)方案:
??=6, ??=1;
??=5, ??=2;
??=4, ??=3.

題目解析:
分糖條件寫(xiě)的很清楚兑宇,兩個(gè)整數(shù)a和b,要求a<b粱坤;
對(duì)于數(shù)字n來(lái)說(shuō)隶糕,如果n是偶數(shù),那么有n/2-1種可能站玄;
如果n是奇數(shù)枚驻,那么有n/2種可能;
利用計(jì)算機(jī)整除的特性株旷,可以表述為(n-1)/2再登;


int main(int argc, const char * argv[]) {
    // insert code here...
    
    int t;
    cin >> t;
    while (t--) {
        int n;
        cin >> n;
        cout << (n - 1) / 2 << endl;
    }   
    
    return 0;
}

題目2

題目鏈接
題目大意:
有三個(gè)正整數(shù)n尔邓,a,b锉矢,現(xiàn)在需要構(gòu)造一個(gè)字符串s梯嗽,長(zhǎng)度為n,只包含小寫(xiě)字母沽损,并且滿足要求:
字符串s中灯节,任何長(zhǎng)度為a的子串要包含b個(gè)不同的字符。

輸入:
第一行绵估,整數(shù)??表示有t個(gè)樣例數(shù)量 (1≤??≤2000)
接下來(lái)每個(gè)樣例一行炎疆,四個(gè)整數(shù) ??, ?? and ?? (1≤??≤??≤2000,1≤??≤min(26,??))

輸出:
每個(gè)樣例一行,輸出滿足要求的字符串国裳;(題目保證答案一定存在)

Examples
input
4
7 5 3
6 1 1
6 6 1
5 2 2
output
tleelte
qwerty
vvvvvv
abcde

題目解析:
題目的要求是形入,長(zhǎng)度為a的子串中,有b個(gè)不同的字符缝左;
那么將b個(gè)字符構(gòu)成的字符串不斷重復(fù)亿遂,即可滿足題目要求;
比如說(shuō)題目樣例 7 5 3
b=3盒使,則用abc不斷循環(huán)崩掘,得到abcabca
樣例 5 2 2
b=2七嫌,則用ab不斷循環(huán)少办,得到ababa

實(shí)現(xiàn)較為簡(jiǎn)單。


int main(int argc, const char * argv[]) {
    // insert code here...
    
    int t;
    cin >> t;
    while (t--) {
        int n, a, b;
        cin >> n >> a >> b;
        int k = 0;
        for (int i = 0; i < n; ++i) {
            putchar('a' + k);
            k = (k + 1) % b;
        }
        puts("");
    }   
    
    return 0;
}

題目3

題目鏈接
題目大意:
有n個(gè)整數(shù)a[i]诵原,現(xiàn)在需要從中選擇兩組數(shù)字英妓,要求:
1、兩組數(shù)字的數(shù)量一樣绍赛,每個(gè)整數(shù)只能劃分到一個(gè)組內(nèi)蔓纠;
2、第一組的數(shù)字各不相同吗蚌,第二組的數(shù)字完全相同腿倚;
現(xiàn)在希望兩組數(shù)字盡可能的多,問(wèn)最多一組能有幾個(gè)整數(shù)蚯妇。

輸入:
第一行敷燎,整數(shù)??表示有t個(gè)樣例數(shù)量 (1≤??≤10000)
接下來(lái)每個(gè)樣例兩行,第一行整數(shù)?? (1≤??≤2?1e5)
第二行n個(gè)整數(shù) ??1,??2,…,???? (1≤????≤??),

輸出:
每個(gè)樣例一行箩言,整數(shù)x硬贯,表示一組最多能夠有x個(gè)整數(shù)。

Examples
input
4
7
4 2 4 1 4 3 4
5
2 1 5 4 3
1
1
4
1 1 1 3
?output
?3
?1
?0
?2

題目解析:
假如沒(méi)有要求2陨收,那么直接平分饭豹,x最大值就是n/2;
單獨(dú)考慮不同數(shù)字的情況,直接算出數(shù)組中有k個(gè)不同的整數(shù)q拄衰,再算出數(shù)組中最多重復(fù)的整數(shù)w;
大多數(shù)情況下它褪,min(q, w)就是答案了。
但是存在q和w會(huì)公用一個(gè)整數(shù)翘悉,比如說(shuō)1.2.3,3,3這種情況列赎,或者1.2.3.4.5.2.2情況。

當(dāng)w<=q-1的時(shí)候镐确,重復(fù)的數(shù)字比較少包吝,所以答案就是w;
如果w>q-1的時(shí)候源葫,重復(fù)的數(shù)字比較多诗越,那么優(yōu)先把重復(fù)的數(shù)字分配到第一組,答案就是min(w-1,q)息堂;

int a[N];
map<int, int> hmap;

int main(int argc, const char * argv[]) {
    // insert code here...
    
    int t;
    cin >> t;
    while (t--) {
        int n;
        cin >> n;
        hmap.clear();
        int maxCount = 0;
        for (int i = 0; i < n; ++i) {
            int k;
            cin >> k;
            ++hmap[k];
            maxCount = max(maxCount, hmap[k]);
        }
        
        if (hmap.size() <= maxCount - 1) {
            cout << hmap.size() << endl;
        }
        else {
            cout << min((int)hmap.size() - 1, maxCount) << endl;
        }
    }   
    
    return 0;
}

題目4

題目鏈接
題目大意:
長(zhǎng)度為n的字符串嚷狞,一共有三種字符,'B', 'R', '?'荣堰;
'?'的字符需要填充為'B'或者'R'床未;
現(xiàn)在小明不喜歡相連兩個(gè)字符是一樣的, 現(xiàn)在需要知道怎么填充使得最終相連兩個(gè)字符相同的情況盡可能少振坚?
比如說(shuō)"BRRRBBR"就有3個(gè)相連的字符相同薇搁,"BB"出現(xiàn)一次,"RR"出現(xiàn)兩次渡八;

輸入:
第一行啃洋,整數(shù)??表示有t個(gè)樣例數(shù)量 (1≤??≤100)
接下來(lái)每個(gè)樣例兩行,第一行整數(shù)?? (1≤??≤100)
第二行長(zhǎng)度為n的字符串s

輸出:
每個(gè)樣例一行屎鳍,輸出由'B'和'R'字符串構(gòu)成的字符串宏娄。

Examples
input
5
7
?R???BR
7
???R???
1
?
1
B
10
?R??RB??B?

output
BRRBRBR
BRBRBRB
B
B
BRRBRBBRBR

題目解析:
方案1,動(dòng)態(tài)規(guī)劃逮壁,dp[i][2]表示前i個(gè)字符孵坚,第i個(gè)字符為B、R的最小重復(fù)次數(shù)窥淆;
初始化的時(shí)候卖宠,如果第1個(gè)字符是?則dp[1][0]=dp[1][1]=0祖乳;
第1個(gè)字符是B逗堵,則dp[1][0]=0,dp[1][1]=n;(n是極大值眷昆,表示dp[1][1]不可妊殉印)
第1個(gè)字符是R汁咏,則dp[1][1]=0,dp[1][0]=n;(n是極大值作媚,表示dp[1][0]不可热撂病)
狀態(tài)轉(zhuǎn)移的時(shí)候,dp[i]可以由dp[i-1]來(lái)進(jìn)行計(jì)算纸泡;
如果a[i]==B漂问,則dp[i][0] = min(dp[i-1][0]+1, dp[i-1][1]); dp[i][1]=n;
如果a[i]==R女揭,則dp[i][1] = min(dp[i-1][1]+1, dp[i-1][0])蚤假; dp[i][1]=n;
這樣看最終dp[n]的最小值即可。

方案2吧兔,找到第一個(gè)不為?的字符磷仰,從這個(gè)位置分別向左右開(kāi)始填充,每次優(yōu)先選擇相鄰字符不相同的方案境蔼;
??R??
RBRBR

方案3灶平,通過(guò)數(shù)學(xué)直接計(jì)算;
從左到右箍土,如果第i個(gè)字符串前面??沒(méi)有確定字符逢享,則這段?不會(huì)產(chǎn)生特殊字符;若吴藻?瞒爬?前面有確定字符k,則根據(jù)a[i]和a[k]以及(i-k)可以直接計(jì)算出來(lái)有多少個(gè)相同字符调缨;(0或者1)

考慮到題目要輸出結(jié)果疮鲫,還是方案2比較簡(jiǎn)單吆你。

思考??:
如果是要連續(xù)3個(gè)字符串不一樣呢弦叶?

class Solution {
    static const int N = 200010;
    string str;
    char ans[N];

public:
    void solve() {
        int t;
        cin >> t;
        while (t--) {
            int n;
            cin >> n;
            cin >> str;
            int pos = n;
            for (int i = 0; i < n; ++i) {
                if (str[i] != '?') {
                    pos = i;
                    break;
                }
            }
            ans[n] = '\0';
            if (pos == n) {
                for (int i = 0; i < n; ++i) {
                    ans[i] = i % 2 ? 'B' : 'R';
                }
            }
            else {
                ans[pos] = str[pos];
                for (int i = pos - 1; i >= 0; --i) {
                    if (str[i] == '?') {
                        ans[i] = 'B' + 'R' - ans[i + 1];
                    }
                    else {
                        ans[i] = str[i];
                    }
                }
                for (int i = pos + 1; i < n; ++i) {
                    if (str[i] == '?') {
                        ans[i] = 'B' + 'R' - ans[i - 1];
                    }
                    else {
                        ans[i] = str[i];
                    }
                }
            }
            printf("%s\n", ans);
        }
    }
}
ac;

題目5

題目鏈接
題目大意:
從n個(gè)整數(shù)的數(shù)組中,找到(i, j) 要求 l ≤ a[i]+a[j] ≤ r妇多,問(wèn)有多少(i, j)符合要求伤哺;

輸入:
第一行是整數(shù)t,表示有t個(gè)樣例 (1≤??≤10000 ).
每個(gè)樣例第一行是整數(shù)??,??,?? (1≤??≤2?1e5, 1≤??≤??≤1e9)
第二行是n個(gè)整數(shù)??1,??2,…,???? (1≤????≤109).

輸出:
(??,??)的數(shù)量者祖,要求是 (??<??) 并且 ??≤????+????≤??.

Examples
input
4
3 4 7
5 1 2
5 5 8
5 1 2 4 3
4 100 1000
1 1 1 1
5 9 13
2 5 5 1 1

output
yes
2
7
0
1

題目解析:
題目要求的是任意a[i]和a[j]立莉,那么數(shù)組的順序沒(méi)有意義,可以直接將數(shù)組進(jìn)行排序七问;
如果不考慮復(fù)雜度蜓耻,我們可以枚舉pair(i, j)是否滿足要求,這樣復(fù)雜度是N*N械巡;
由于排序完之后刹淌,數(shù)組是有序的饶氏,我們?cè)诿杜epair(i, j)的時(shí)候,可以采用下面的策略:
從小到大枚舉i有勾,假設(shè)已經(jīng)先取了數(shù)字a[i]并且i<j疹启,要求是找到l<=a[i]+a[j]<=r,那么就是在區(qū)間[i+1, n]里面找到l-a[i]作為起點(diǎn)蔼卡,r-a[i]作為終點(diǎn)的區(qū)間喊崖;
我們可以采用二分查找來(lái),也可以使用快捷方法lower_bound雇逞。


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

public:
    void solve() {
        int t;
        cin >> t;
        while (t--) {
            int n, l, r;
            cin >> n >> l >> r;
            for (int i = 0; i < n; ++i) {
                cin >> a[i];
            }
            sort(a, a + n);
            lld sum = 0;
            for (int i = 0; i + 1 < n; ++i) {
                int left = l - a[i];
                int right = r - a[i] + 1;
                // 從i+1開(kāi)始荤懂,找到第一個(gè)大于等于left的數(shù)字作為起點(diǎn)x
                int x = lower_bound(a + i + 1, a + n, left) - a;
                if (x >= n) {
                    continue;;
                }
                // 新x開(kāi)始,找到第一個(gè)大于right的數(shù)字作為終點(diǎn)y
                int y = lower_bound(a + x, a + n, right) - a;
                sum += y - x;
            }
            cout << sum << endl;
        }
    }
}
ac;

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末塘砸,一起剝皮案震驚了整個(gè)濱河市势誊,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌谣蠢,老刑警劉巖粟耻,帶你破解...
    沈念sama閱讀 206,126評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異眉踱,居然都是意外死亡挤忙,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,254評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門(mén)谈喳,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)册烈,“玉大人,你說(shuō)我怎么就攤上這事婿禽∩蜕” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 152,445評(píng)論 0 341
  • 文/不壞的土叔 我叫張陵扭倾,是天一觀的道長(zhǎng)淀零。 經(jīng)常有香客問(wèn)我,道長(zhǎng)膛壹,這世上最難降的妖魔是什么驾中? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,185評(píng)論 1 278
  • 正文 為了忘掉前任,我火速辦了婚禮模聋,結(jié)果婚禮上肩民,老公的妹妹穿的比我還像新娘。我一直安慰自己链方,他們只是感情好持痰,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,178評(píng)論 5 371
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著祟蚀,像睡著了一般工窍。 火紅的嫁衣襯著肌膚如雪占调。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 48,970評(píng)論 1 284
  • 那天移剪,我揣著相機(jī)與錄音究珊,去河邊找鬼。 笑死纵苛,一個(gè)胖子當(dāng)著我的面吹牛剿涮,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播攻人,決...
    沈念sama閱讀 38,276評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼取试,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了怀吻?” 一聲冷哼從身側(cè)響起瞬浓,我...
    開(kāi)封第一講書(shū)人閱讀 36,927評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎蓬坡,沒(méi)想到半個(gè)月后猿棉,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,400評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡屑咳,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,883評(píng)論 2 323
  • 正文 我和宋清朗相戀三年萨赁,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片兆龙。...
    茶點(diǎn)故事閱讀 37,997評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡杖爽,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出紫皇,到底是詐尸還是另有隱情慰安,我是刑警寧澤,帶...
    沈念sama閱讀 33,646評(píng)論 4 322
  • 正文 年R本政府宣布聪铺,位于F島的核電站化焕,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏计寇。R本人自食惡果不足惜锣杂,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,213評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望番宁。 院中可真熱鬧,春花似錦赖阻、人聲如沸蝶押。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,204評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)棋电。三九已至茎截,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間赶盔,已是汗流浹背企锌。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,423評(píng)論 1 260
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留于未,地道東北人撕攒。 一個(gè)月前我還...
    沈念sama閱讀 45,423評(píng)論 2 352
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像烘浦,于是被迫代替她去往敵國(guó)和親抖坪。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,722評(píng)論 2 345

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