算法竞赛进阶指南|算法竞赛进阶指南0x08 总结练习(下)

数的进制转换 编写一个程序,可以实现将一个数字由一个进制转换为另一个进制。
这里有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 #includeusing 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 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<

耍杂技的牛 农民约翰的N头奶牛(编号为1…N)计划逃跑并加入马戏团,为此它们决定练习表演杂技。
奶牛们不是非常有创意,只提出了一个杂技表演:
叠罗汉,表演时,奶牛们站在彼此的身上,形成一个高高的垂直堆叠。
奶牛们正在试图找到自己在这个堆叠中应该所处的位置顺序。
这N头奶牛中的每一头都有着自己的重量Wi以及自己的强壮程度Si。
【算法竞赛进阶指南|算法竞赛进阶指南0x08 总结练习(下)】一头牛支撑不住的可能性取决于它头上所有牛的总重量(不包括它自己)减去它的身体强壮程度的值,现在称该数值为风险值,风险值越大,这只牛撑不住的可能性越高。
您的任务是确定奶牛的排序,使得所有奶牛的风险值中的最大值尽可能的小。
输入格式
第一行输入整数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 pairusing namespace std; const int N=50010; pll cows[N]; int n; bool CMP(const pll &a,const pll &b) { return a.first+a.second

最大的和 给定一个包含整数的二维矩阵,子矩形是位于整个阵列内的任何大小为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 #includeusing 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

任务 今天某公司有M个任务需要完成。
每个任务都有相应的难度级别和完成任务所需时间。
第i个任务的难度级别为yi,完成任务所需时间为xi分钟。
如果公司完成此任务,他们将获得(500 * xi + 2 * yi)美元收入。
该公司有N台机器,每台机器都有最长工作时间和级别。
如果任务所需时间超过机器的最长工作时间,则机器无法完成此任务。
如果任务难度级别超过机器的级别,则机器无法完成次任务。
每台机器一天内只能完成一项任务。
每个任务只能由一台机器完成。
请为他们设计一个任务分配方案,使得该公司能够最大化他们今天可以完成的任务数量。
如果有多种解决方案,他们希望选取赚取利润最高的那种。
输入格式
输入包含几个测试用例。
对于每个测试用例,第一行包含两个整数N和M,分别代表机器数量和任务数量。
接下来N行,每行包含两个整数xi,yi,分别代表机器最长工作时间和机器级别。
再接下来M行,每行包含两个整数xi,yi,分别代表完成任务所需时间和任务难度级别。
输出格式
对于每个测试用例,输出两个整数,代表公司今天可以完成的最大任务数以及他们将获得的收入。
数据范围
1≤N,M≤100000,
0 0≤yi≤100
输入样例:
1 2
100 3
100 2
100 1
输出样例:
1 50004
贪心策略:按第一个为第一关键字,第二个为第二关键字排序,真的没什么好说的,和防晒那题很像,基操hh,因为第二关键字根本无法改变局面,最多也只有100。~ 。~
#include #include #include #include#define pii pair #define ll long longusing 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 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<

    推荐阅读