编写一个程序,可以实现将一个数字由一个进制转换为另一个进制。
这里有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
#include
#include
#include
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
#include
#include
#define ll long long
#define pll pair
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
#include
#include
#include
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
输入样例:
1 2
100 3
100 2
100 1
输出样例:
1 50004
贪心策略:按第一个为第一关键字,第二个为第二关键字排序,真的没什么好说的,和防晒那题很像,基操hh,因为第二关键字根本无法改变局面,最多也只有100。~ 。~
#include
#include
#include
#include
#define pii pair
#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;
}