數的進制轉換
編寫一個程序,可以實現將一個數字由一個進制轉換爲另一個進制。
這裏有62個不同數位{0-9,A-Z,a-z}。
輸入格式
第一行輸入一個整數,代表接下來的行數。
接下來每一行都包含三個數字,首先是輸入進制(十進制表示),然後是輸出進制(十進制表示),最後是用輸入進製表示的輸入數字,數字之間用空格隔開。
輸入進制和輸出進制都在2到62的範圍之內。
(在十進制下)A = 10,B = 11,…,Z = 35,a = 36,b = 37,…,z = 61 (0-9仍然表示0-9)。
輸出格式
對於每一組進制轉換,程序的輸出都由三行構成。
第一行包含兩個數字,首先是輸入進制(十進制表示),然後是用輸入進製表示的輸入數字。
第二行包含兩個數字,首先是輸出進制(十進制表示),然後是用輸出進製表示的輸入數字。
第三行爲空白行。
同一行內數字用空格隔開。
輸入樣例:
8
62 2 abcdefghiz
10 16 1234567890123456789012345678901234567890
16 35 3A0C92075C0DBF3B8ACBC5F96CE3F0AD2
35 23 333YMHOUE8JPLT7OX6K9FYCQ8A
23 49 946B9AA02MI37E3D3MMJ4G7BL2F05
49 61 1VbDkSIMJL3JjRgAdlUfcaWj
61 5 dl9MDSWqwHjDnToKcsWE1S
5 10 42104444441001414401221302402201233340311104212022133030
輸出樣例:
62 abcdefghiz
2 11011100000100010111110010010110011111001001100011010010001
10 1234567890123456789012345678901234567890
16 3A0C92075C0DBF3B8ACBC5F96CE3F0AD2
16 3A0C92075C0DBF3B8ACBC5F96CE3F0AD2
35 333YMHOUE8JPLT7OX6K9FYCQ8A
35 333YMHOUE8JPLT7OX6K9FYCQ8A
23 946B9AA02MI37E3D3MMJ4G7BL2F05
23 946B9AA02MI37E3D3MMJ4G7BL2F05
49 1VbDkSIMJL3JjRgAdlUfcaWj
49 1VbDkSIMJL3JjRgAdlUfcaWj
61 dl9MDSWqwHjDnToKcsWE1S
61 dl9MDSWqwHjDnToKcsWE1S
5 42104444441001414401221302402201233340311104212022133030
5 42104444441001414401221302402201233340311104212022133030
10 1234567890123456789012345678901234567890
這是一道非常基礎的進制轉化題,A進制->B進制,但是要用高精度,一般思維是先A->10,然後10->B,但是這題的做法可以一步到位,A->B,回顧一下10->B進制,我們ans.push_back(a%B) a/=B,這是我們基於10進制的除法,那我們如果能實現a關於A進制的除法,我們是不是就能一步到位了呢?~ 。~,來看代碼。
#include<iostream>
#include<string>
#include<algorithm>
#include<vector>
using namespace std;
inline int get(char ch)
{
if(ch>='A'&&ch<='Z') return ch-'A'+10;
else if(ch>='a'&&ch<='z') return ch-'a'+36;
return ch-'0';
}
inline char out(int num)
{
if(num<=9&&num>=0) return num+'0';
else if(num>=10&&num<=35) return num-10+'A';
else return num-36+'a';
}
int main(){
//freopen("data.in","r",stdin);
//freopen("data.out","w",stdout);
int T;
cin>>T;
while(T--)
{
int a1,a2;
string s1,s2;
cin>>a1>>a2>>s1;
vector<int> v;
for(auto ch:s1)
v.push_back(get(ch));
reverse(v.begin(),v.end());
while(v.size())
{
int t=0;
for(int i=v.size()-1;i>=0;i--)
{
t=a1*t+v[i];
v[i]=t/a2;
t%=a2;
}
s2.push_back(out(t));
while(v.size()&&v.back()==0) v.pop_back();
}
reverse(s2.begin(),s2.end());
cout<<a1<<" "<<s1<<endl<<a2<<" "<<s2<<endl;
puts("");
}
return 0;
}
耍雜技的牛
農民約翰的N頭奶牛(編號爲1…N)計劃逃跑並加入馬戲團,爲此它們決定練習表演雜技。
奶牛們不是非常有創意,只提出了一個雜技表演:
疊羅漢,表演時,奶牛們站在彼此的身上,形成一個高高的垂直堆疊。
奶牛們正在試圖找到自己在這個堆疊中應該所處的位置順序。
這N頭奶牛中的每一頭都有着自己的重量Wi以及自己的強壯程度Si。
一頭牛支撐不住的可能性取決於它頭上所有牛的總重量(不包括它自己)減去它的身體強壯程度的值,現在稱該數值爲風險值,風險值越大,這隻牛撐不住的可能性越高。
您的任務是確定奶牛的排序,使得所有奶牛的風險值中的最大值儘可能的小。
輸入格式
第一行輸入整數N,表示奶牛數量。
接下來N行,每行輸入兩個整數,表示牛的重量和強壯程度,第i行表示第i頭牛的重量Wi以及它的強壯程度Si。
輸出格式
輸出一個整數,表示最大風險值的最小可能值。
數據範圍
1≤N≤50000,
1≤Wi≤10,000,
1≤Si≤1,000,000,000
輸入樣例:
3
10 3
2 5
3 3
輸出樣例:
2
和那個國王遊戲挺像的,我們按強壯+體重重的牛排個序就行了。
#include<iostream>
#include<cstring>
#include<algorithm>
#define ll long long
#define pll pair<ll,ll>
using namespace std;
const int N=50010;
pll cows[N];
int n;
bool CMP(const pll &a,const pll &b)
{
return a.first+a.second<b.first+b.second;
}
int main(){
//freopen("data.in","r",stdin);
//freopen("data.out","w",stdout);
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%lld%lld",&cows[i].first,&cows[i].second);
sort(cows+1,cows+n+1,CMP);
ll temp=0;
ll res=-100000000000;
for(int i=1;i<=n;i++)
{
res=max(res,temp-cows[i].second);
temp+=cows[i].first;
}
printf("%lld\n",res);
return 0;
}
最大的和
給定一個包含整數的二維矩陣,子矩形是位於整個陣列內的任何大小爲1 * 1或更大的連續子陣列。
矩形的總和是該矩形中所有元素的總和。
在這個問題中,具有最大和的子矩形被稱爲最大子矩形。
例如,下列數組:
0 -2 -7 0
9 2 -6 2
-4 1 -4 1
-1 8 0 -2
其最大子矩形爲:
9 2
-4 1
-1 8
它擁有最大和15。
輸入格式
輸入中將包含一個N*N的整數數組。
第一行只輸入一個整數N,表示方形二維數組的大小。
從第二行開始,輸入由空格和換行符隔開的N2個整數,它們即爲二維數組中的N2個元素,輸入順序從二維數組的第一行開始向下逐行輸入,同一行數據從左向右逐個輸入。
數組中的數字會保持在[-127,127]的範圍內。
輸出格式
輸出一個整數,代表最大子矩形的總和。
數據範圍
1≤N≤100
輸入樣例:
4
0 -2 -7 0 9 2 -6 2
-4 1 -4 1 -1
8 0 -2
輸出樣例:
15
這個題就是最長子序和的二維版本,一維用暴力,一維用DP就可以了hh,沒什麼好說的,來看代碼。
#include<iostream>
#include<cstring>
#include<algorithm>
#include<limits.h>
using namespace std;
const int N=110;
int g[N][N];
int n;
int main(){
//freopen("data.in","r",stdin);
//freopen("data.out","w",stdout);
cin>>n;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
cin>>g[i][j];
g[i][j]+=g[i-1][j];
}
int res=INT_MIN;
for(int i=1;i<=n;i++)
for(int j=0;j<i;j++)
{
int last=0;
for(int k=1;k<=n;k++)
{
last=max(last,0)+g[i][k]-g[j][k];
res=max(res,last);
}
}
cout<<res<<endl;
return 0;
}
任務
今天某公司有M個任務需要完成。
每個任務都有相應的難度級別和完成任務所需時間。
第i個任務的難度級別爲yi,完成任務所需時間爲xi分鐘。
如果公司完成此任務,他們將獲得(500 * xi + 2 * yi)美元收入。
該公司有N臺機器,每臺機器都有最長工作時間和級別。
如果任務所需時間超過機器的最長工作時間,則機器無法完成此任務。
如果任務難度級別超過機器的級別,則機器無法完成次任務。
每臺機器一天內只能完成一項任務。
每個任務只能由一臺機器完成。
請爲他們設計一個任務分配方案,使得該公司能夠最大化他們今天可以完成的任務數量。
如果有多種解決方案,他們希望選取賺取利潤最高的那種。
輸入格式
輸入包含幾個測試用例。
對於每個測試用例,第一行包含兩個整數N和M,分別代表機器數量和任務數量。
接下來N行,每行包含兩個整數xi,yi,分別代表機器最長工作時間和機器級別。
再接下來M行,每行包含兩個整數xi,yi,分別代表完成任務所需時間和任務難度級別。
輸出格式
對於每個測試用例,輸出兩個整數,代表公司今天可以完成的最大任務數以及他們將獲得的收入。
數據範圍
1≤N,M≤100000,
0<xi<1440,
0≤yi≤100
輸入樣例:
1 2
100 3
100 2
100 1
輸出樣例:
1 50004
貪心策略:按第一個爲第一關鍵字,第二個爲第二關鍵字排序,真的沒什麼好說的,和防曬那題很像,基操hh,因爲第二關鍵字根本無法改變局面,最多也只有100。~ 。~
#include<iostream>
#include<algorithm>
#include<cstring>
#include<set>
#define pii pair<int,int>
#define ll long long
using namespace std;
const int N=100010;
pii mach[N],task[N];
int n,m;
inline int calc(const pii &p)
{
return 500*p.first+2*p.second;
}
int main(){
//freopen("data.in","r",stdin);
//freopen("data.out","w",stdout);
while(cin>>n>>m)
{
for(int i=1;i<=n;i++)
cin>>mach[i].first>>mach[i].second;
for(int i=1;i<=m;i++)
cin>>task[i].first>>task[i].second;
sort(mach+1,mach+n+1);
sort(task+1,task+m+1);
multiset<int> s;
ll res=0,cnt=0;
for(int i=m,j=n;i>=1;i--)
{
while(j>=1&&task[i].first<=mach[j].first) s.insert(mach[j--].second);
auto it=s.lower_bound(task[i].second);
if(it!=s.end())
{
res+=calc(task[i]);
s.erase(it);
cnt++;
}
}
cout<<cnt<<" "<<res<<endl;
}
return 0;
}