神秘金币(贪心)

思路

每个时刻都可以收集一枚金币,那么对于任意一枚金币,只要想收集,就一定可以收集到。

所以我们只需要收集价值是前kk大的金币,按时间依次收集即可。

代码

#include <bits/stdc++.h>
#define int long long
using namespace std;

const int tt=1e5+10;
int t[tt],v[tt];

bool cmp(int a,int b){
	return a>b;
}

signed main(){
	freopen("coin.in","r",stdin);
	freopen("coin.out","w",stdout);
	int n,k;
	cin >>n>>k;
	for(int i=1;i<=n;i++){
		cin >>t[i];
	}
	for(int i=1;i<=n;i++){
		cin >>t[i];
	}
	int ans=0;
	sort(t+1,t+1+n,cmp);
	for(int i=1;i<=k;i++){
		ans+=t[i];
	}
	cout <<ans;
	return 0;
}

学习乘法(数学)

思路没想到的原因

其实代码的基本框架已经写好了,但是忘记看数据范围了:a,b999999a,b≤999999,并不是忘记开longlong longlong,而是在计算最终答案时没有加上高精乘,导致只有6060分。

思路

首先,我们要知道:

对于和相同的两个数,它们的差值越小,乘积越大。

也就是我们所说的差小积大

所以我们可以去枚举整个字符串,当发现a[i]a[i]b[i]b[i]不同时(记为idxidx),就从idx+1idx+1开始。

如果这时的a[i]>b[i]a[i]>b[i],就交换这两个数字。

代码

#include <bits/stdc++.h>
using namespace std;

bool cmp(string a,string b){
	return a>b;
}

int find(string a,string b){
	long long res=0;
	for(int i=0;i<a.size();i++){
		if(a[i]!=b[i]){
			res=i;
			return res+1;
		}
	}
	return res+1;
}

vector<int> mul(vector<int> A,long long b){
    vector<int> C;
    int t=0;
    for(int i=0;i<A.size()||t;i++){
      	if(i<A.size()) t+=A[i]*b;
      	C.push_back(t%10);
      	t/=10;
    }
    while(C.size()>1&&C.back()==0) C.pop_back();
    return C;
}

int main(){
	freopen("mul.in","r",stdin);
	freopen("mul.out","w",stdout);
	string a,b;
	cin >>a>>b;
	if(!cmp(a,b)){
		swap(a,b);
	}
	long long idx=find(a,b);
	for(int i=idx;i<a.size();i++){
		if(a[i]>b[i]) swap(a[i],b[i]);
	}
	vector<int> res;
	for(int i=a.size()-1;i>=0;i--){
		res.push_back(a[i]-'0');
	}
	auto ans=mul(res,stoi(b));
	for(int i=ans.size()-1;i>=0;i--){
		cout <<ans[i];
	}
	return 0;
}

饮料难题(数学)

思路

其实答案是n/(k1)n/(k-1),为什么呢?我们可以来证明一下。

kk个瓶子 =1=1瓶饮料+1+1瓶的饮料

(k1)(k-1)个瓶子=1=1瓶的饮料

nn 个瓶子=n/(k1)=n/(k-1)瓶的饮料

所以最终的答案是n/(k1)n/(k-1)

tipstips:瞅一眼数据范围n10100000n≤10^{100000}说实话,这是真的逆天),你会想到什么?没错,就是用高精除!

代码

#include <bits/stdc++.h>
#define int long long
using namespace std;

vector<int> div(vector<int> a,int b){
	vector<int> c;
	int r=0;
	int t=0;
	for(int i=a.size()-1;i>=0;i--){
		t=r*10+a[i];
		c.push_back(t/b);
		r=t%b;
	}
	reverse(c.begin(),c.end());
	while(c.size()>1&&c.back()==0){
		c.pop_back();
	}
	return c;
}

signed main(){
	freopen("drink.in","r",stdin);
	freopen("drink.out","w",stdout);
	string n;
	int k;
	cin >>n>>k;
	k-=1;
	vector<int> res,ans;
	for(int i=n.size()-1;i>=0;i--){
		res.push_back(n[i]-'0');
	}
	ans=div(res,k);
	for(int i=ans.size()-1;i>=0;i--){
		cout <<ans[i];
	}
	return 0;
}

手术(大模拟&set)

待更新……

谢谢