第一次打bc BestCoder Round #84

今晚第一次打bc,之前bc給我的影響是很難。。。不像cf前兩道題是水題來的(但自己每次都拿不下,基礎太差~~)。感覺bc也不是想像的那麼難(前兩題),但是因爲自己基礎差所以思考打碼的時間比較長,bc也是測試小部分數據而已,所以當第一題顯示ac的時候我以爲過了,但誰知最後還是沒能ac。不夠細心.........

發現bc基本上都是數論題,,,靠智商捉急~~~

第一題:

問題描述
給出一個不定方程x_{0}+2x_{1}+4x_{2}+...+2^{m}x_{m}=nx0+2x1+4x2+...+2mxm=n, 找出一組解(x_0,x_1,x_2,...,x_m)(x0,x1,x2,...,xm), 使得\displaystyle\sum_{i=0}^{m} x_ii=0mxi最小, 並且每個x_ixi (0 \le i \le m0im)都是非負的.
輸入描述
輸入包含多組數據, 第一行包含一個整數TT (1 \le T \le 10^5)(1T105)表示測試數據組數. 對於每組數據:

第一行包含兩個整數nnmm (0 \le n,m \le 10^9)(0n,m109).
輸出描述
對於每組數據, 輸出\displaystyle\sum_{i=0}^{m} x_ii=0mxi的最小值.
一看就是關於二進制的問題,但是需要考慮當m小於n二進制的位數時的情況,就是這裏沒考慮不清楚wa了,當p(記錄n的二進制位數)大於m時,需要向最高位不斷乘以2才能補充超過m位以後的值。。。。自己表達不清楚,,,,例如當n=15(1111),m=1,當p>2時,第三位需要乘以2,第四位需要乘以4(2*2)。。。。

#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;
#define N 10000
int b[N];
int main() {

#ifndef ONLINE_JUDGE
    freopen("in.txt","r",stdin);
#endif
    int t,n,m;
    cin>>t;
    while(t--){
        cin>>n>>m;
        int k=0,p=0,a=n,s=0,r=1;
        m++;
        while(a){
            if(a&1) b[k++]=1;
            else b[k++]=0;
            a>>=1;
        }
        for(int i=0;i<k;i++){
            //cout<<b[i];
            p++;
            if(p>m){
                r*=2;
                if(b[i]) s+=r;
            }
            else{
                if(b[i]) s++;
            }
        }
        if(m==1) cout<<n<<endl;
        else
        cout<<s<<endl;
    } 
}


第二題:

問題描述
Peter有一個序列a_1,a_2,...,a_na1,a2,...,an. 定義F(a_1,a_2,...,a_n)=(f_1,f_2,...,f_n)F(a1,a2,...,an)=(f1,f2,...,fn), 其中f_ifi是以a_iai結尾的最長上升子序列的長度.

Peter想要找到另一個序列b_1,b_2,...,b_nb1,b2,...,bn使得F(a_1,a_2,...,a_n)F(a1,a2,...,an)F(b_1,b_2,...,b_n)F(b1,b2,...,bn)相同. 對於所有可行的正整數序列, Peter想要那個字典序最小的序列.

序列a_1, a_2, ..., a_na1,a2,...,anb_1, b_2, ..., b_nb1,b2,...,bn字典序小, 當且僅當存在一個正整數ii (1 \le i \le n)(1in)滿足對於所有的kk (1 \le k < i)(1k<i)都有a_k = b_kak=bk並且a_i < b_iai<bi.
輸入描述
輸入包含多組數據, 第一行包含一個整數TT表示測試數據組數. 對於每組數據:

第一行包含一個整數nn (1 \le n \le 100000)(1n100000)表示序列的長度. 第二行包含nn個整數a_1,a_2,...,a_na1,a2,...,an (1 \le a_i \le 10^9)(1ai109).
輸出描述
對於每組數據, 輸出nn個整數b_1,b_2,...,b_nb1,b2,...,bn (1 \le b_i \le 10^9)(1bi109)表示那個字典序最小的序列.
輸入樣例
3
1
10
5
5 4 3 2 1
3
1 3 5
輸出樣例
1
1 1 1 1 1
1 2 3

其實剛開始以爲很複雜,很煩,而且過的人也不是很多,。、、、誰知看題解才忽然明白,其實就是求以ai(0《i<n)結尾的最長上升子序列的個數。,,

最小的字典序就是f1,f2,f3......

再次複習一次求最長上升子序列,但是這題O(n^2)做法會超時,需要nlongn。。。。複習了一遍nlongn的做法,但是不注意細節,wa了十幾遍了,唉 ~~~~基礎搭不牢~~~

wa的過程真的很痛苦,看不出哪裏有問題但是一直wa的過程真的很費力,很煩躁~~~~

#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;
#define N 100010
#define inf 999999
long long a[N],n,b[N],c[N];
int main() {

#ifndef ONLINE_JUDGE
	freopen("in.txt","r",stdin);
#endif
    int t;
    cin>>t;
    while(t--)
    {
    	cin>>n;
    	for(int i=0;i<n;i++)
    	cin>>a[i];
    	for(int i=0;i<=n;i++)
    	b[i]=inf;
    	int k=0;
    	b[k++]=a[0];c[0]=1;
    	for(int i=1;i<n;i++){
    		if(a[i]>b[k-1])
    		{
    			b[k++]=a[i];c[i]=k;   //注意不是c[i]=c[i-1]+1; 
			}
			else{
				int x=lower_bound(b,b+k,a[i])-b;
				//cout<<"x:"<<x<<endl;
				b[x]=a[i];
				c[i]=x+1;
			}
		}
		/*for(int i=0;i<n;i++)
		cout<<b[i]<<" ";
		cout<<"------"<<endl;*/
		for(int i=0;i<n-1;i++)
		cout<<c[i]<<" ";
		cout<<c[n-1]<<endl;
	}
}



連接:

BestCoder Round #84

 

hdu:5747,5748

發佈了86 篇原創文章 · 獲贊 38 · 訪問量 8萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章