習題訓練計畫 2020 05 26

2022-07-23 03:18:11 字數 4475 閱讀 5773

a題:看到題目把所有的數兩兩配對,以為n一定是偶數,wa了。

題目沒有明確說明n是偶數,因此n也可能為奇數。

思路就是先把陣列排一遍序,然後從中間開始往兩邊輸出陣列中的數。由於n可以為奇數,所以迴圈條件不是i>=1&&j<=n,而是i>=1||j<=n。

**如下:

#include

using namespace std;

typedef long long ll;

int a[100000+8];

int main()

int t,i,j,k,m,n;

cin>>t;

while(t--)

cin>>n;

for(i=1;i<=n;i++)

cin>>a[i];

sort(a+1,a+n+1);

for(i=n/2,j=n/2+1;i>=1||j<=n;i--,j++)

if(j<=n)

cout=1)

coutb題:wa了6次。下面介紹wa的原因

wa的思路:找到第乙個下降點,然後找下降點後面的最小值,求出下降點和最小值的差,然後計算2^0+2^1+…+2^k,直到和》=這個差,輸出k+1.

正確思路:找到所有下降點與其之後的最小值的差,再找出所有差中的最大值,然後計算2^0+2^1+…+2^k,直到和》=這個差,輸出k+1.

錯誤的原因就是沒有考慮有多個下降點的情況,比如:1 7 5 9 3,

**如下:

#include

using namespace std;

typedef long long ll;

int a[100000+8];

ll quickmi(int a,int b)

ll ans=1,base=a;

while(b!=0)

if(b&1==1)

ans*=base;

base*=base;

b>>=1;

return ans;

int main()

int t,n,i,j,k;

cin>>t;

while(t--)

cin>>n;

k=0;

int flag=0;

for(i=1;i<=n;i++)

cin>>a[i];

int p=0;

int ma=a[1];

for(i=2;i<=n;i++)

ma=max(ma,a[i]);

if(a[i]p=max(p,ma-a[i]);

if(p==0)

cout<<"0"ll sum=0;

j=0;

while(sumsum+=quickmi(2,j);

j++;

//cout<<"sum=="if(j==1)

base=1;

else

base*=2;

sum+=base;

if(sum>=p)

break;

coutc題:思路:先把所有的數從大到小排序,然後從頭開始sum+a[i],判斷sum/i是否小於x,如果小於,直接break輸出i-1,**如下:

#include

using namespace std;

typedef long long ll;

int a[100000+8];

bool cmp(int i,int j)

return i>j;

int main()

int t,n,i,j,k,x;

cin>>t;

while(t--)

cin>>n>>x;

int flag=0;

for(i=1;i<=n;i++)

cin>>a[i];

sort(a+1,a+n+1,cmp);

ll sum=0;

int k=0;

for(i=1;i<=n;i++)

sum+=a[i];

if(sum/ibreak;

coutd題:wa了兩次。

wa的思路:先找出a[i]最小的點,然後打爆他,之後用子彈補傷害。事實證明我想的太簡單了,反例:7  15

2  14

3  1

正確思路:先判斷每乙個怪物在遭受上乙個怪物的**傷害後的血量,如果》0,就先用槍把這個怪物的血量打到和上乙個怪物造成的**傷害相同為止,最後找出此時血量最低的怪物,引爆他,便能形成乙個連環**,並且使每乙個怪物死亡。

另外一定要注意輸入要用scanf,而不是cin,

正確**:

#include

using namespace std;

typedef long long ll;

ll a[300000+8],b[300000+8];

bool cmp(int i,int j)

return i>j;

int main()

int n,t,i,j,k,m;

cin>>t;

while(t--)

scanf("%d",&n);

ll ans=0;

for(i=1; i<=n; i++)

scanf("%lld%lld",&a[i],&b[i]);

if(a[1]<=b[n])

else

ans+=a[1]-b[n];

a[1]=b[n];

for(i=2; i<=n; i++)

if(a[i]<=b[i-1])

else

ans+=a[i]-b[i-1];

a[i]=b[i-1];

ll mi=a[1];

for(i=1;i<=n;i++)

if(a[i]mi=a[i];

ans+=mi;

coute題:思路:從頭開始記錄i之前陣列a中是否出現過1、-1,然後比較a[i]和b[i]是否相等,如果不相等,那麼比較a[i]是否大於b[i],如果大於,我們需要讓此時的a[i]不斷減去-1以達到==b[i]的目的,也就是說,如果在i之前沒有出現過-1,就直接輸出no;如果a[i]小於b[i],我們需要讓a[i]不斷+1來達到目的,所以在i之前必須出現1,如果沒有出現直接輸出no。

最後如果滿足上述條件,輸出yes即可。

wa了一次是因為我為了提高效率把對陣列a和陣列b的比較直接放在了陣列b輸入的迴圈中,然後使用cin.clear(),cin.sync()清除快取來避免上乙個樣例的影響。沒有通過應該是vj的檢測系統的問題,具體不明。

**如下:

#include

using namespace std;

typedef long long ll;

int a[300000+8],b[300000+8];

bool cmp(int i,int j)

return i>j;

int main()

int n,i,j,k,t,m;

cin>>t;

while(t--)

scanf("%d",&n);

for(i=1; i<=n; i++)

scanf("%d",&a[i]);

int flag1=0,flag=0;

for(i=1; i<=n; i++)

scanf("%d",&b[i]);

for(i=1; i<=n; i++)

if(a[i]!=b[i])

if(a[i]if(flag1==0)

cout<<"no"

else if(a[i]>b[i])

if(flag==0)

cout<<"no"

if(a[i]==1)

flag1=1;

if(a[i]==-1)

flag=1;

if(i==n+1)

cout<<"yes"f題:字首和。

用k記錄與此時的字首和相等的最近的上一次字首和的位置,k的初始值為-1,那麼此時的位置-k-1便是以此時的位置為右邊界點的合法字串的個數。

正確**:

#include

using namespace std;

typedef long long ll;

ll a[300000+8],b[300000+8];

bool cmp(int i,int j)

return i>j;

int main()

ll n,i,j;

maph;

map::iterator p;

cin>>n;

ll sum=0;

ll ans=0;

h[0]=0;

ll k=-1;

for(i=1;i<=n;i++)

cin>>a[i];

sum+=a[i];

p=h.find(sum);

if(p!=h.end())

k=max(k,h[sum]);

ans+=i-k-1;

h[sum]=i;

cout

ACM訓練計畫

都快乙個學期了,都目前為止都沒有寫部落格的習慣,感覺之前學習的很多知識早就忘了,學習效率很低,所以今天特意抽出乙個下午的時間,來思考,並學習一下其他大神的學習和訓練計畫。先貼個圖 來自sduoj 這圖是對於一道題,你所需要做的事情。接下來是做題所遵循的規則 1 多看 書,少看 2 100行左右的 不...

口才訓練計畫

歡迎進入這裡朋友,你好,很高興認識你。正所謂不是一家人就不進一家門,進了一家門就是一家人了,我想你和我一樣都有積極的人生,都嚮往著自己能夠把握著一種神奇的力量,能夠改變自己的人生,可是,憑什麼呢?沒說兩句話就把心愛的姑娘給嚇跑了 當眾演講,沒兩句話就語塞了說不下去 面對應試,一陣臉紅,就胡說八道了。...

口才訓練計畫

歡迎進入這裡朋友,你好,很高興認識你。正所謂不是一家人就不進一家門,進了一家門就是一家人了,我想你和我一樣都有積極的人生,都嚮往著自己能夠把握著一種神奇的力量,能夠改變自己的人生,可是,憑什麼呢?沒說兩句話就把心愛的姑娘給嚇跑了 當眾演講,沒兩句話就語塞了說不下去 面對應試,一陣臉紅,就胡說八道了。...