【華為機試線上訓練】Day3

HelloZEX發表於2018-08-01

題目描述

輸入一個int型整數,按照從右向左的閱讀順序,返回一個不含重複數字的新的整數。

輸入描述:

輸入一個int型整數

輸出描述:

按照從右向左的閱讀順序,返回一個不含重複數字的新的整數

#include <stdio.h>
int main(void){
    int n,m;
    int a[10]={0,0,0,0,0,0,0,0,0,0};//標記
    scanf("%d",&n);
    while(n){
       m=n%10;
       if(a[m]!=1){
          a[m]=1;
          printf("%d",m);
       }
       n=n/10;
    }
    return 0;
}


題目描述

編寫一個函式,計算字串中含有的不同字元的個數。字元在ACSII碼範圍內(0~127)。不在範圍內的不作統計。

輸入描述:

輸入N個字元,字元在ACSII碼範圍內。

輸出描述:

輸出範圍在(0~127)字元的個數。

/*C++
輸入字元,ascii值在[0,127]時插入集合set中,輸出set中的元素個數。*/
#include<iostream>
#include<set>
using namespace std;
int main()
{
    char c;
    set<char> s;
    while(cin>>c){
        if(c>=0 && c<=127){
            s.insert(c);
        }
    }
    cout << s.size() <<endl;
}


題目描述

描述:

輸入一個整數,將這個整數以字串的形式逆序輸出

程式不考慮負數的情況,若數字含有0,則逆序形式也含有0,如輸入為100,則輸出為001

輸入描述:

輸入一個int整數

輸出描述:

將這個整數以字串的形式逆序輸出

#include <stdio.h>
//#include <string.h>
int main(void)
{
    int i, k;
    scanf("%d", &k);
    if (k == 0)
        printf("%d", k);
    while(k!=0)
    {
        i = k % 10;
        printf("%d", i);
        k = k / 10;
    }
    return 0;
 
}


題目描述

寫出一個程式,接受一個字串,然後輸出該字串反轉後的字串。例如:

輸入描述:

輸入N個字元

輸出描述:

輸出該字串反轉後的字串

#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
int main()
    {
    string s;
    getline(cin,s);
    reverse(s.begin(),s.end());
    cout<<s<<endl;
    return 0;
}


題目描述

將一個英文語句以單詞為單位逆序排放。例如“I am a boy”,逆序排放後為“boy a am I”
所有單詞之間用一個空格隔開,語句中除了英文字母外,不再包含其他字元
介面說明

/**
 * 反轉句子
 * 
 * @param sentence 原句子
 * @return 反轉後的句子
 */
public String reverse(String sentence);

輸入描述:

將一個英文語句以單詞為單位逆序排放。

輸出描述:

得到逆序的句子

#include<iostream>
#include<string>
#include<sstream>
#include<vector>
 
using namespace std;
int test1_main(){
    string str;
    getline(cin,str);
    stringstream ss(str);
    string res="",temp;
    while(ss>>temp){
        if(res=="")
            res=temp;
        else
            res=temp+" "+res;
 
    }
    cout<<res;
    cout<<endl;
    return 0;
}
 
int /*test2_*/main(){
    string str;
    vector<string> strVec;   
    while(cin>>str){
        strVec.push_back(str);
    } 
    for(auto it=strVec.end()-1;it>=strVec.begin();it--){
        cout<<*it;
        if(it!=strVec.begin()){
            cout<<" ";          
        }
    }
    cout<<endl;
    return 0;
}


題目描述

給定n個字串,請對n個字串按照字典序排列。

輸入描述:

輸入第一行為一個正整數n(1≤n≤1000),下面n行為n個字串(字串長度≤100),字串中只含有大小寫字母。

輸出描述:

資料輸出n行,輸出結果為按照字典序排列的字串。

#include <iostream>
#include <string>
#include <map>
#include <algorithm>
using namespace std;
 
bool compare(const string &s1, const string &s2) {
    return s1<s2;
}
 
int main(){
    int n;
    vector<string> result;
    while(cin >> n){
        while(n!=0){
            n--;
            string t;
            cin >> t;
            result.push_back(t);
        }
        sort(result.begin(),result.end(),compare);
        for(int i = 0;i<result.size();i++){
            cout << result[i] << endl;
        }
    }
}


題目描述

輸入一個int型的正整數,計算出該int型資料在記憶體中儲存時1的個數。

輸入描述:

 輸入一個整數(int型別)

輸出描述:

 這個數轉換成2進位制後,輸出1的個數

#include<iostream>
using namespace std;
int main()
{
    int a,count;
    cin >> a;
     
    count = 0;
    while(a>0)
    {
        if(a&1)
            count++;
        a >>= 1;
    }
    cout << count << endl;
}


題目描述

王強今天很開心,公司發給N元的年終獎。王強決定把年終獎用於購物,他把想買的物品分為兩類:主件與附件,附件是從屬於某個主件的,下表就是一些主件與附件的例子:

主件 附件
電腦 印表機,掃描器
書櫃 圖書
書桌 檯燈,文具
工作椅

如果要買歸類為附件的物品,必須先買該附件所屬的主件。每個主件可以有 0 個、 1 個或 2 個附件。附件不再有從屬於自己的附件。王強想買的東西很多,為了不超出預算,他把每件物品規定了一個重要度,分為 5 等:用整數 1 5 表示,第 5 等最重要。他還從因特網上查到了每件物品的價格(都是 10 元的整數倍)。他希望在不超過 N 元(可以等於 N 元)的前提下,使每件物品的價格與重要度的乘積的總和最大。

    設第 j 件物品的價格為 v[j] ,重要度為 w[j] ,共選中了 k 件物品,編號依次為 j 1 , j 2 ,……, j k ,則所求的總和為:

v[j 1 ]*w[j 1 ]+v[j 2 ]*w[j 2 ]+ … +v[j k ]*w[j k ] 。(其中 * 為乘號)

    請你幫助王強設計一個滿足要求的購物單。

輸入描述:

輸入的第 1 行,為兩個正整數,用一個空格隔開:N m

(其中 N ( <32000 )表示總錢數, m ( <60 )為希望購買物品的個數。)

從第 2 行到第 m+1 行,第 j 行給出了編號為 j-1 的物品的基本資料,每行有 3 個非負整數 v p q

(其中 v 表示該物品的價格( v<10000 ), p 表示該物品的重要度( 1 5 ), q 表示該物品是主件還是附件。如果 q=0 ,表示該物品為主件,如果 q>0 ,表示該物品為附件, q 是所屬主件的編號)

輸出描述:

 輸出檔案只有一個正整數,為不超過總錢數的物品的價格與重要度乘積的總和的最大值( <200000 )。

參考:https://blog.csdn.net/wly_2014/article/details/51223592

解題思路:這是一道揹包問題。

先考慮解決揹包問題,思路是這樣:比如說這道題目,給定總錢數N,共有m件商品可以購買,從這m件商品中選擇購買商品,使得購買商品的錢數不超過N,同時滿足一定的條件K(如上面提到的每件商品的重要度與其價錢相乘的乘積之和最大)。

現在開始購買了並且我們手裡有N元錢,我們從第m件商品開始考慮。對於第m件商品,首先我們要看我們手頭的N元錢是不是能夠付得起買第m件商品的錢。

1、如果手頭的錢N元買不起第m件商品。那麼我們就放棄這件商品,拿上這N元錢去買前m-1件商品。(這就轉化為原問題的一個子問題,我覺得我不考慮子問題怎麼解,子問題讓別人幫我解。繼續往下走)

2、如果我手頭的N元錢買的起第m件商品。那麼我也有兩種選擇

2.1 第一種選擇,我不買第m件商品,我用N元錢買前m-1件商品,我看看我能達到到的條件K是什麼。對於這道題目就是v[j 1 ]*w[j 1 ]+v[j 2 ]*w[j 2 ]+ … +v[j k ]*w[j k ]的最大值。(這就轉化為原問題的一個子問題,我覺得我不考慮子問題怎麼解,子問題讓別人幫我解。繼續往下走)

2.2第二種選擇,我買下第m件商品,這用我花掉了v[m]元錢,還剩下N-v[m]元錢。我再用剩下的錢去買前m-1件商品。這樣我也可以淺出一個v[j 1 ]*w[j 1 ]+v[j 2 ]*w[j 2 ]+ … +v[j k ]*w[j k ]的最大值。(這就轉化為原問題的一個子問題,我覺得我不考慮子問題怎麼解,子問題讓別人幫我解。繼續往下走)

如果2.1和2.2的情況我都能得到結果了,我就比較這兩種情況,看哪個能使我的利益最大化,我就選哪個方案。至此,問題就算完成了。而題目的要求只是稍微與上面的問題有所不同,稍作修改即可。

 

下面就根據上面的思路列方程:

假設我們用value[i][j]來表示用j元錢,給定前i個物品(1、2、...、i)供你選擇來購買方案的情況下v[j 1 ]*w[j 1 ]+v[j 2 ]*w[j 2 ]+ … +v[j k ]*w[j k ] 能夠達到的最大值。根據上面的分析有:

1、手頭的錢j元買不起第i件商品。value[i][j]=value[i-1][j](注意:下面的c++程式中這裡的value[i][j]=0,如果我寫成前面的話通不過一個測試用例,具體我也沒有搞清楚為什麼。)

2、對應前面的第2中方案,j元買得起第i件商品

2.1value[i][j] = value[i-1][j]

2.2 value[i][j] = value[i -1][j - v[i]] + w[i]

虛擬碼:

for (int i = 1; i <= m; i++)

for (int j = 1; j <= N; j++)

{

if (j < v[i]) { 

value[i][j] = value[i - 1][j];

}

else {

value[i][j] = max(value[i - 1][j], value[i - 1][j - v[i]] + w[i];

}

}

本題程式碼:只是把上述問題的解稍作修改即可滿足,具體如下。

#include <iostream>
#include <vector>
#include <bitset>
using namespace std;
struct Goods
{
	int v;
	int p;
	int q;
	Goods() : v(0), p(0), q(0){
	}
};
int max(int a, int b)
{
	return (a > b ? a : b);
}
int main(void)
{
	int N, m;
	vector<Goods> goods;
	cin >> N >> m;
	
	Goods temp;
	goods.push_back(temp);//第0個元素不使用
	for (int i = 1; i <= m; i++){
		cin >> temp.v >> temp.p >> temp.q;
		goods.push_back(temp);
	}
 
	vector<vector<int> > value(m + 1, vector<int> (N + 1));
	for (int i = 0; i <= m; i++){
		value[i][0] = 0;
	}
	for (int j = 0; j <= N; j++){
		value[0][j] = 0;
	}
 
	for (int i = 1; i <= m; i++){
		for (int j = 1; j <= N; j++)
		{
			if (goods[i].v > j){
				//value[i][j] = value[i - 1][j];
				value[i][j] = 0;
			}
			else {
				int master = goods[i].q;
				if (master == 0){
					value[i][j] = max(value[i - 1][j], value[i - 1][j - goods[i].v] + goods[i].p * goods[i].v);
				}
				else {
					if (goods[i].v + goods[master].v > j)
					{
						//value[i][j] = value[i - 1][j];
						value[i][j] = 0;
					}
					else {
						value[i][j] = max(value[i - 1][j], value[i - 1][j - goods[i].v - goods[master].v] + goods[i].p * goods[i].v + goods[master].p * goods[master].v);
					}
				}
				
			}
		}
	}
	cout << value[m][N] << endl;
	return 0;
}

 

相關文章