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;
}
posted @ 2024-07-20 12:22  小卷同学  阅读(75)  评论(0)    收藏  举报