7-2 分香肠
简单来说,就是切的每一刀都是平均切的,所有把所有的香肠拼在一起,区分真切和切在交界点的情况,就可以求出最终答案了。
另外,有一个明确的公式:解=M-gcd(N,M) (gcd即最大公约数)
#include <iostream>
using namespace std;
int main()
{
int n,m;cin>>n>>m;
long long sum=0;
for(int i=0;i<=m*n;i+=n){
if(i%m!=0)sum++;
}
cout<<sum;
return 0;
}
7-3 h0145. 会议安排
结构体排序,调用cmp函数,方法还是挺熟悉的,思路在考试的时候没有想到,总的来说就是将所有的活动按照结束时间排序,然后再从头往后取活动,确保后一个活动开始时间在上一个结束时间之后就行,遍历完输出答案即可。
#include<iostream>
#include<algorithm>
using namespace std;
struct huodong{
int begin;
int end;
};
bool cmp(huodong x,huodong y){
return x.end<y.end;
}
int main(){
int m;cin>>m;
while(m--){
int n;cin>>n;
huodong a[10005];
for(int i=0;i<n;i++)cin>>a[i].begin>>a[i].end;
sort(a,a+n,cmp);
int ans=0;int time=0;
for(int i=0;i<n;i++){
if(time<=a[i].begin){
ans++;
time=a[i].end;
}
}
cout<<ans<<endl;
}
return 0;
}
7-4 神秘密码
递归求解,在调用的函数中分段输入,很好地解决了递归调用函数的时候表达式的表述问题,本来想把输入写在主函数然后利用strmpy函数写但是没有写对,最后还是用这种方法写了:
#include<iostream>
using namespace std;
string w(){
char a;int n;
string ans;
while(cin>>a){
if(a=='['){
cin>>n;
string p=w();
while(n--)ans+=p;
}
else if(a==']')return ans;
else ans+=a;
}
return ans;
}
int main(){
string t=w();
cout<<t;
return 0;
}
7-5 h0114.国王游戏
#include<iostream>
#include<utility>
#include<vector>
#include<algorithm>
using namespace std;
//存储每个大臣左右手的数字
pair<int, int> ab[1000];
//高精的结构体,便于主函数的操作,同时练习一下课程刚学的运算符
struct High
{
//每一位的数字
vector<int> places;
//运算符*,计算一个高精数乘以一个int
High operator* (const int& number)
{
//结果
High r;
//暂存当前的进位结果
int n = 0;
for (int i = 0; i < places.size(); i++)
{
n += places[i] * number;
r.places.push_back(n % 10);
n /= 10;
}
//将超出原位数的位存入结果数
while (n != 0)
{
r.places.push_back(n % 10);
n /= 10;
}
//去0
while (r.places.back() == 0 && r.places.size() > 1)
{
r.places.pop_back();
}
return r;
}
//运算符/,用于计算高精除int
High operator/(const int& number)
{
//结果
High r;
//当前从上一位剩余的数
int n = 0;
//除法从高位往低位进行
for (int i = places.size() - 1; i >= 0; i--)
{
n *= 10;
n += places[i];
r.places.push_back(n / number);
//求余数
n %= number;
}
//这样得到的数每一位是过来的,需要反转
reverse(r.places.begin(), r.places.end());
//去0
while (r.places.back() == 0 && r.places.size() > 1)
{
r.places.pop_back();
}
return r;
}
//运算符>,比较两个高精数的大小
bool operator>(const High& number)
{
//位数不同时,位数大的大
if (number.places.size() != places.size())
{
return places.size() > number.places.size();
}
//位数相同时,从高位开始逐个判断
else
{
for (int i = places.size() - 1; i >= 0; i--)
{
if (places[i] != number.places[i])
{
return places[i] > number.places[i];
}
}
return false;
}
}
//无参构造函数
High(){}
//用一个int初始化高精
High(int n)
{
while (n != 0)
{
places.push_back(n % 10);
n /= 10;
}
}
//运算符<<,用于输出高精数
friend ostream& operator<<(ostream& out, High& high)
{
for (int i = high.places.size() - 1; i >= 0; i--)
{
out << high.places[i];
}
return out;
}
};
int main()
{
//大臣数、国王左手数、国王右手数
int n, a, b;
//结果
High ans;
cin >> n >> a >> b;
for (int i = 0; i < n; i++)
{
int aa, bb;
cin >> aa >> bb;
ab[i] = make_pair(aa, bb);
}
//对大臣排序,规则为上述规则
sort(ab, ab + n, [](pair<int, int> left, pair<int, int> right){return left.first * left.second < right.first * right.second;});
//给答案设置初始值为第一个大臣的奖赏
ans = High(a / ab[0].second);
//当前大臣前面所有人左手数乘积
High h(a);
//遍历第二个大臣开始的所有大臣
for (int i = 1; i < n; i++)
{
//更新乘积
h = h * ab[i - 1].first;
//这个大臣的奖赏
High m = h / ab[i].second;
//更新答案
if (m > ans)
{
ans = m;
}
}
cout << ans << endl;
return 0;
}