CF1138B Circus 數學 方程暴力求解

2021-09-13 01:14:42 字數 2119 閱讀 4502

題目鏈結

給出n(保證是偶數)個人的資料,其中c[i]為1表示此人可以扮演小丑,a[i]為1表示此人可以扮演藝術家,然後讓你把這群人分成兩組.

有三點要求

兩組人數必須相等.

第一組的小丑數量必須等於第二組的藝術家數量

乙個人只能被分在乙個組裡面

第一行給出n(2<=n<=5000)

隨後一行給出n個數字,數字只會是01中的乙個,第i個數表示c[i]

隨後一行給出n個數字,數字只會是01中的乙個,第i個數表示a[i]

輸出在第一場**現的演員的編號(不限順序,且若有多種方案,輸出任意一種即可),以空格分隔

題意非常簡單明瞭.我們不難想到把人可以分為4種

我們用a,b,c,d來表示這四種人的總數量(在**中使用了cnt1,cnt2…)

用a1,b1,c1,d1表示在第一場**現的某種類的數量

用a2,b2,c2,d2表示在第二場**現的某種類的數量

我們能得到兩個恒等式

a1+b1+c1+d1 =n/2

a1+b1+2*c1 = a+c

我們有四個未知數,有兩個方程,如果根據情況討論的話情況太過複雜,所以我們考慮資料範圍並不大,故採用暴力列舉的方式來解此方程組,我們只需要窮舉b1,c1的取值,就能通過方程2解出a1,然後將這三個數帶入方程1,就能解出來d1,如果a1,d1都合法,則得到了方程的解,然後再輸出編號即可.

若無解則輸出-1.

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define ll long long

using namespace std;

void

ioinit()

struct peo peo[

5100];

int cnt1 =

0, cnt2 =

0, cnt3 =

0, cnt4 =0;

intmain()

for(

int i =

0; i < n;

++i)

for(

int i =

0; i < n;

++i)

else

if(peo[i]

.c ==

'0'&& peo[i]

.a ==

'1')

else

if(peo[i]

.c ==

'1'&& peo[i]

.a ==

'0')

else

}// cout << cnt1 << cnt2 << cnt3 << cnt4 << endl;

for(

int b1 =

0; b1 <= cnt3;

++b1)

else

if(a1 && peo[i]

.c ==

'0'&& peo[i]

.a ==

'1')

else

if(b1 && peo[i]

.c ==

'1'&& peo[i]

.a ==

'0')

else

if(c1 && peo[i]

.c ==

'1'&& peo[i]

.a ==

'1')

} cout << endl;

return0;

}}cout <<

"-1"

<< endl;

return0;

}

這種數學暴力的方式實在是讓我沒想到,一直在各種分情況討論,看來面對數學問題應當多多注意其資料範圍,適當使用暴力能夠方便解題.

51nod 1138 數學 等差數列

思路 很顯然每個連續的序列都是等差數列,那麼我們利用等差數列求和公式。s a1 a1 k 1 k 2 2 a1 k 1 k 2 a1是首項,k是個數。列舉k,首項最小為1,k最大,具體不說了,反正大致就是sqrt 2 n 列舉量還是在平方以內 題外話 這題就是沒有去想等差數列,等差數列公式和求和要熟...

51nod 1138 數學 等差數列

思路 很顯然每個連續的序列都是等差數列,那麼我們利用等差數列求和公式。s a1 a1 k 1 k 2 2 a1 k 1 k 2 a1是首項,k是個數。列舉k,首項最小為1,k最大,具體不說了,反正大致就是sqrt 2 n 列舉量還是在平方以內 題外話 這題就是沒有去想等差數列,等差數列公式和求和要熟...

CF280C Game on Tree 數學期望

n 個點的一棵樹,每次選擇乙個沒有染色的點把它和它的子樹染黑,求期望全部染黑的步數。可以理解為我們按照乙個順序輪流染色,如果乙個點有祖先節點在它前面就不用計算貢獻。也就是如果乙個點要計算貢獻的概率就是它要排在所有它的祖先節點前面,也就是 frac 求個和就好了。時間複雜度 o n include i...