【题解】算法典当铺章节3

2530:把各个进制先转化为10进制,然后模拟进位即可

#include<iostream>
#include<cstring>
using namespace std;
char sx[17]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
int main(){
	string st;
	string s;
	int c = 0;
	cin >> st;
	cin >> s;
	if(s=="0"){
		puts("0");
		puts("0");
		puts("0");
		puts("0");
		return 0;
	}
	//先转换为10进制
	
	for(int i=0;i<s.size();i++){
		int x =0;
		if(s[i]=='A')x=10;
		else if(s[i]=='B')x=11;
		else if(s[i]=='C')x=12;
		else if(s[i]=='D')x=13;
		else if(s[i]=='E')x=14;
		else if(s[i]=='F')x=15;
		else x=s[i]-'0';
		if(st=="BIN") c = c*2+x;
		if(st=="OCT") c = c*8+x;
		if(st=="DEC") c = c*10+x;
		if(st=="HEX") c = c*16+x;
	}
	string ans = "";
	for(int x=c;x>0;x/=16)ans = sx[x%16]+ans;
	cout << ans <<endl;ans = "";
	for(int x=c;x>0;x/=10)ans = sx[x%10]+ans;
	cout << ans <<endl;ans = "";
	for(int x=c;x>0;x/=8)ans = sx[x%8]+ans;
	cout << ans <<endl;ans = "";
	for(int x=c;x>0;x/=2)ans = sx[x%2]+ans;
	cout << ans <<endl;
	return 0;	
}

2531:二分查找,也可以使用upperbound返回大于X的第一个数,用迭代器和distance函数返回 距离

#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
using LL = long long;
const int N = 100010;
LL q[N];
int main(){
	int n,t;
	cin >> n >>t;
	vector<LL>all;
	for(int i=0;i<n;i++){
		LL xx;
		cin >>xx;
		all.push_back(xx);
	}
	sort(all.begin(),all.end());
	while(t--){
		LL x;
		cin >>x;
		vector<LL>::iterator it = upper_bound(all.begin(),all.end(),x);
		int d = distance(all.begin(),it);
		cout << all.size()-d<<endl;
	}
	return 0;
}

二分代码:

#include<iostream>
#include<algorithm>

using namespace std;

const int N = 100010;
int q[N];
int main(){
	int n,m;
	cin >> n >> m;
	for(int i=0;i<n;i++){
		cin >> q[i];
	}
	sort(q,q+n);
	while(m--){
		int l=0,r=n,x;
		cin >> x;
		while(l<r){
			int mid = l+r>>1;
			if(q[mid]>x)r=mid;
			else l=mid+1;
		}
		cout << n-l<<endl;
	}
	return 0;
}

2532:二分,注意向上取整l+r+1>>1

什么时候需要向上取整避免死循环呢,l = mid+1不需要,r = mid-1需要

#include<iostream>

using namespace std;
const int N = 100010;

int n,m,q[N];
bool check(int x){
	int cnt = 0;
	for(int i=0;i<n;i++){
		if(a[i]>x)cnt += q[i]-x;
	}
	return cnt >= m;
}
int main(){
	cin >> n >> m;
	for(int i=0;i<n;i++){
		cin >> q[i];
	}
	int l=0,r=2e5;
	while(l<r){
		int mid = l+r+1>>1;
		if(check(mid))l=mid;
		else r =mid-1;
	}
	cout << l <<endl;
	return 0;
}

2533,第一回合一定可以造成一次伤害,那么假设经过 x回合恰好使用了 n 次第 i 个攻击,可以得到 x=1+(n−1)×ci​。只有当 x 增加一个 ci时才会让攻击次数增加,所以下取整就能得到 x 回合之后用了几次攻击。

#include<iostream>
#define int long long
using namespace std;
int n, h;
pair<int, int> e[200010];
bool check(int x) {
	int res = 0;
	for (int i = 1; i <= n; i++) {
		res += ((x - 1 + e[i].second) / e[i].second) * e[i].first;
	}
	return res >= h;
}
signed main() {
	cin >> h >> n;
	for (int i = 1; i <= n; i++) {
		cin >> e[i].first;
	}
	for (int i = 1; i <= n; i++) {
		cin >> e[i].second;
	}
	int l = 0, r = 4e14;
	while (l < r) {
		int mid = (l + r ) / 2;
		if (check(mid)) {
			r = mid;
		} else {
			l = mid + 1;
		}
	}
	cout << l << endl;
	return 0;
}

2534:三进制+高精度

把 m 换成 3 进制,设转换后为 x,位数有 s 位。

当 xi≠0(1≤i≤s),则可以在右盘加 3s−i 重的砝码。

若 xi=2,则xi+1​ 加一,左盘砝码加一,因为一个砝码只有一个。

若 xi=3,则xi+1​ 加一即可。

#include <bits/stdc++.h>
using namespace std;
struct node {
	int t[ 110 ], len;
	node() {
		memset( t, 0, sizeof t );
		t[ 1 ] = 1;
		len = 1;
	}
	void tim() {
		for ( int i = 1 ; i <= len ; i ++ )
			t[ i ] *= 3;
		for ( int i = 1 ; i <= len ; i ++ )
			t[ i + 1 ] += t[ i ] / 10, t[ i ] %= 10;
		if ( t[ len + 1 ] > 0 )
			len ++;
	}
	void print() {
		for ( int i = len ; i >= 1 ; i -- )
			printf( "%d", t[ i ] );
		putchar( ' ' );
	}
};
vector< int > a;
vector< node > l, r;

char c[ 110 ];
int len;

int div() {
	int t, num = 0;
	for ( int i = 1 ; i <= len ; i ++ ) {
		t = ( num + c[ i ] ) % 3;
		c[ i ] = ( num + c[ i ] ) / 3;
		num = t * 10;
	}
	return t;
}
bool ept() {
	for ( int i = 1 ; i <= len ; i ++ )
		if ( c[ i ] > 0 )
			return false;
	return true;
}

void input() {
	scanf(" %s", c + 1 );
	len = strlen( c + 1 );
	for ( int i = 1 ; i <= len ; i ++ )
		c[i] -= '0';
	while ( ! ept() ) {
		a.push_back( div() );
	}
	a.push_back(0);
}
signed main() {
	input();
	node base;
	for ( int i = 0 ; i < a.size() ; i ++ ) {
		if ( a[i] == 3 ) {
			a[i] = 0;
			a[i+1] ++;
		}
		if ( a[i] == 2 ) {
			l.push_back( base );
			a[i] = 0;
			a[i+1] ++;
		}
		if ( a[i] == 1 ) {
			r.push_back( base );
		}
		base.tim();
	}
	if (!l.size()) {
		cout << "0";
	} else {
		for ( int i = 0 ; i < l.size() ; i ++ )
			l[i].print();
	}
	printf( "\n");
	for ( int i = 0 ; i < r.size() ; i ++ )
		r[ i ].print();
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值