ACM暑假第一次测试(排序,二分,高精度)--代码题解
A: LOL如何拯救小学生(肥肠煎蛋)
点击查看代码
#define _CRT_SECURE_NO_WARNINGS 1
#define all(C) C.begin(),C.end()
#define S second
#define F first
#define PB push_back
#define mod 1000000007
#define import ios_base::sync_with_stdio(false);cin.tie(NULL)
#include <cstring>
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <string>
#include <vector>
#include <map>
using namespace std;
typedef long long LL;
typedef vector<int> VI;
const int N = 1e5 + 10;
int n, k;
int q[N],p[N];
signed main() {
int t; cin >> t; //输入次数
getchar(); // 跳过空格
while (t--) {
string s;
getline(cin,s); //输入字符串
for(int i=0;i<s.size();i++){
if(s[i]>='a' && s[i]<='z') s[i]-=32; //把所有单词变成大写
}
cout << s[0]; //输出第一单词首字母大写
for(int i=1;i<s.size();i++){
if(s[i]==' '&& s[i+1]!=' '){ //注意中间可能有很多空格
cout << s[i+1]; //输出不是空格的即可
}
}
cout <<endl;
}
return 0;
}
B: 车厢重组(一样的题你还不会?)
点击查看代码
#define _CRT_SECURE_NO_WARNINGS 1
#define all(C) C.begin(),C.end()
#define S second
#define F first
#define PB push_back
#define mod 1000000007
#define import ios_base::sync_with_stdio(false);cin.tie(NULL)
#include <cstring>
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <string>
#include <vector>
#include <map>
using namespace std;
typedef long long ll;
const int N = 2e6 + 10;
int n;
int q[N],p[N];
ll cnt;
void merge_sort(int q[], int l, int r)
{
if (l >= r) return;
int mid = l + r >> 1;
merge_sort(q, l, mid);
merge_sort(q, mid + 1, r);
int i = l, j = mid+1,k=0;
while (i<=mid && j<=r)
{
if(q[i]<=q[j]) p[k++] = q[i++];
else
{
p[k++] = q[j++];
cnt += mid - i + 1; //这其实就是逆序对
}
}
while (i <= mid) p[k++] = q[i++];
while (j <= r) p[k++] = q[j++];
for (int i = l, k = 0; i <= r;++i) q[i] = p[k++];
}
signed main()
{
cin >> n;
for (int i = 0; i < n; ++i) cin >> q[i];
merge_sort(q, 0, n-1);
cout << cnt << endl;
return 0;
}
C: 高精度阶乘的和
点击查看代码
#define _CRT_SECURE_NO_WARNINGS 1
#define all(C) C.begin(),C.end()
#define S second
#define F first
#define PB push_back
#define mod 1000000007
#define import ios_base::sync_with_stdio(false);cin.tie(NULL)
#include <cstring>
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <string>
#include <vector>
#include <map>
using namespace std;
typedef long long LL;
const int N = 1e6 + 10;
string a;
int b,t;
//高精度乘低精度的模板
vector<int> mul(vector<int>A, int 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;
}
//加法模板
vector<int> add(vector<int>A, vector<int> B) {
int t = 0;
vector<int> C;
for (int i = 0; i < A.size() || i<B.size(); ++i) {
if(i<A.size()) t+=A[i];
if(i<B.size()) t+=B[i];
C.push_back(t % 10);
t /= 10;
}
if (t) C.push_back(1);
return C;
}
signed main()
{
int n; cin >> n;
vector<int> C = { 1 };
vector<int> A = { 1 };
for (int i = 2; i <= n; ++i) {
C = mul(C, i); //高精度与低精度的乘积
A = add(A, C); //高精度加法
}
for (int i = A.size()-1; i >=0 ; --i) {
cout << A[i];
}
return 0;
}
D: 阶乘之和
点击查看代码
#define _CRT_SECURE_NO_WARNINGS 1
#define all(C) C.begin(),C.end()
#define S second
#define F first
#define PB push_back
#define mod 1000000007
#define import ios_base::sync_with_stdio(false);cin.tie(NULL)
#include <cstring>
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <string>
#include <vector>
#include <map>
using namespace std;
typedef long long LL;
typedef vector<int> VI;
const int N = 1e5 + 10;
int q[N],p[N];
signed main() {
int t; cin >> t;
while (t--) {
int n;cin >> n;
int tmp=1;
//10的阶乘就是3,628,800,二n最大为1,000,000;
for(int i=1;i<=10;++i){
tmp*=i;
q[i]=tmp;
}
//特判
if(n==0){
cout << "No" <<endl;
continue;
}
int flag=0;
for(int i=10;i>=1;--i){
if(!p[i] && q[i]<=n){
n-=q[i];
p[i]=1; //一个数的阶乘只能用一次
}
if(n==0){
flag=1;
}
}
if(flag) cout <<"Yes" << endl;
else cout << "No" << endl;
memset(p,0,sizeof(p)); //每次都要使得p重置
}
return 0;
}
E: 数的范围 : 典型的整数二分模板题
点击查看代码
#include <bits/stdc++.h>
using namespace std;
const int N = 1e6+10;
int n,t,x;
int q[N];
int serch1(){
int l=-1,r=n;
while(l<r){
int mid = (l+r+1) >> 1;
if(q[mid]<x) l = mid;
else r = mid-1;
}
if(q[l+1]!=x) return -1;
else return l+1;
}
int serch2(){
int l=-1,r=n;
while(l<r){
int mid = (l+r) >> 1;
if(q[mid]>x) r = mid;
else l = mid+1;
}
if(q[r-1]!=x) return -1;
else return r-1;
}
signed main()
{
scanf("%d %d",&n,&t);
for(int i=0;i<n;++i) scanf("%d",&q[i]);
while(t--){
scanf("%d",&x);
int ans1 = serch1();
// if(ans1==-1){
// printf("-1 -1\n");
// continue;
// }
int ans2 = serch2();
printf("%d %d\n",ans1,ans2);
}
return 0;
}
F: 分巧克力
点击查看代码
#include <bits/stdc++.h>
using namespace std;
const int N =1e5+10;
int n,k;
int h[N],w[N];
bool check(int x){
int sum=0;
for(int i=0;i<N;++i){
sum+=(h[i]/x)*(w[i]/x); //这是块数累加
if(sum>=k) return true; //说明还能再大一点
}
return false;
}
signed main(){
cin >> n >> k;
for(int i=0;i<n;++i) cin >> h[i] >> w[i];
int l = 1,r=1e5+10;
while(l+1<r){
int mid = l+r >> 1;
if(check(mid)) l=mid;
else r = mid;
}
cout << l <<endl;
return 0;
}
G: 乘积尾零
点击查看代码
#include <bits/stdc++.h>
using namespace std;
const int N =1010;
signed main()
{
//大数相乘模板题
cout << 31 << endl;
return 0;
}
H: 大数的存储问题
点击查看代码
#include <bits/stdc++.h>
using namespace std;
const int N =1010;
int ans;
vector<int> mul(vector<int> &A,int b)
{
vector<int> C;
for(int i=0,t=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();
for(int i=C.size()-1;i>=0;--i) cout << C[i];
cout << endl;
return C;
}
signed main()
{
vector<int> C={1};
int n;cin >> n;
for(int i=1;i<=n;++i) C = mul(C,i);
return 0;
}
I: 天使的起誓
点击查看代码
#define _CRT_SECURE_NO_WARNINGS 1
#define all(C) C.begin(),C.end()
#define S second
#define F first
#define PB push_back
#define mod 1000000007
#define import ios_base::sync_with_stdio(false);cin.tie(NULL)
#include <cstring>
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <string>
#include <vector>
#include <map>
using namespace std;
typedef long long LL;
const int N = 1e6 + 10;
string a;
LL b,t;
//大数除法的模板题
vector<int> div(vector<int>A, int b) {
vector<int> C;
for (int i = A.size()-1; i>=0; --i) {
t = t * 10 + A[i];
C.push_back(t / b);
t %= b;
}
reverse(C.begin(), C.end());
while (C.size() > 1 && C.back() == 0) C.pop_back();
return C;
}
signed main()
{
vector <int> A, C;
cin >> b >> a;
for (int i = a.size() - 1; i >= 0; --i) A.push_back(a[i] - '0');
C = div(A, b);
cout << t << endl;
return 0;
}
J: 麦森数
点击查看代码
#define _CRT_SECURE_NO_WARNINGS 1
#define all(C) C.begin(),C.end()
#define S second
#define F first
#define PB push_back
#define mod 1000000007
#define import ios_base::sync_with_stdio(false);cin.tie(NULL)
#include <cstring>
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <string>
#include <vector>
#include <map>
using namespace std;
typedef long long LL;
const int N =510;
vector<int> A(N), res(N);
//大数乘大数的模板
vector<int> mul(vector<int>& A, vector<int>& B) {
vector<int> C(2*N);
for (int i = 0; i < 500; ++i) {
for (int j = 0; j < 500; ++j) {
C[i + j] += A[i] * B[j];
}
}
for (int i = 0,t=0; i < 500; ++i) {
t += C[i];
C[i] = t % 10;
t /= 10;
}
return C;
}
//快速幂
void quick_pow(int n) {
res[0] = 1, A[0] = 2;
while (n) {
if (n & 1) res = mul(res, A);
A = mul(A, A);
n >>= 1;
}
res[0]--;
}
signed main()
{
int p; cin >> p;
cout << (int)(log10(2)*p) + 1 << endl;
quick_pow(p);
for(int i=0,k=499;i<10;++i){
for(int j=0;j<50;++j,k--){
printf("%d",res[k]);
}
puts("");
}
return 0;
}
K: 成绩&&奖学金
点击查看代码
//简单的结构体排序
#define _CRT_SECURE_NO_WARNINGS 1
#define all(C) C.begin(),C.end()
#define S second
#define F first
#define PB push_back
#define mod 1000000007
#define import ios_base::sync_with_stdio(false);cin.tie(NULL)
#include <cstring>
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <string>
#include <vector>
#include <map>
using namespace std;
typedef long long ll;
const int N = 2e6 + 10;
struct stu
{
int Id;
int chinese;
int math;
int eglish;
int sum;
}q[N];
bool cmp(stu a, stu b)
{
if (a.sum != b.sum) return a.sum > b.sum;
else if (a.chinese != b.chinese) return a.chinese > b.chinese;
else return a.Id < b.Id;
}
signed main()
{
import;
int n;
cin >> n;
for (int i = 1; i <= n; ++i)
{
cin >> q[i].chinese >> q[i].math >> q[i].eglish;
q[i].Id = i;
q[i].sum = q[i].chinese + q[i].math + q[i].eglish;
}
sort(q + 1, q + n + 1, cmp);
for (int i = 1; i <= 5; ++i) printf("%d %d\n", q[i].Id, q[i].sum);
return 0;
}
L: 一元三次方程求解
点击查看代码
#define _CRT_SECURE_NO_WARNINGS 1
#define all(C) C.begin(),C.end()
#define S second
#define F first
#define PB push_back
#define mod 1000000007
#define import ios_base::sync_with_stdio(false);cin.tie(NULL)
#include <cstring>
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <string>
#include <vector>
#include <map>
using namespace std;
typedef long long LL;
const int N = 1e6 + 10;
double a, b, c, d;
double l, r;
double fun(double x) {
return a * x * x * x + b * x * x + c * x + d;
}
signed main() {
import;
cin >> a >> b >> c >> d;
int sum = 0;
for (int i = -100; i < 100; ++i) {
l = i, r = i + 1;
if (fun(l)==0) { //防止重复,只输出左边
printf("%.2lf ", l);
sum++;
continue;
}
if (fun(l) * fun(r) < 0) { //有解的情况
while (r - l > 0.001) {
double mid = (l + r) / 2;
if (fun(l) * fun(mid) < 0) r = mid;
else l = mid;
}
printf("%.2lf ", r);
sum++;
}
if (sum == 3) break;
}
return 0;
}