• P4109 [HEOI2015]定价


    P4109 [HEOI2015]定价

    题目

    传送门

    思路

    直接上算法:

    分块

    为了尽可能平均,把[0,1e9]分成1e5个块,第i个块为[i*1e4,(i+1)*1e4),不难想到,每一个块的"荒谬度最低的价格"为左端点,即i*1e4,

    然后就是分块的老套路:

    令p表示l所属的块,q表示r所属的块

    1. p==q:暴力
    2. else:把当前区间分成三段:[l,(p+1)*1e4],[(p+1)*1e4,(q-1)*1e4),[q*1e4,r](注意区分括号的意义,还有就是区间重合对结果无影响),结合上面的结论(加粗部分),可以在O(sqrt(r-l))级别内求出答案

    详见代码:

    代码

    AC程序(tested.cpp)

    #include <iostream>
    using namespace std;
    int a[200010];
    int count(int x) {
    	while(x % 10 == 0)x/=10;
    	int res = (x % 10 == 5 ? -1 : 0);
    	while(x != 0) {
    		x /= 10;
    		res += 2; 
    	}
    	return res;
    }
    int GetMin(int l , int r){//暴力求[l,r]的"荒谬度最低的价格"
    	int minn = (1 << 29) , ans;
    	for(int i = l ; i <= r ; i++) {
    		int tmp = count(i);
    		if(tmp < minn)
    			minn = tmp , ans = i;
    	}
    	return ans; 
    }
    int main() {
    	int t;
    	cin >> t;
    	while(t--) {
    		int l ,r;
    		int minn = (1 << 29) , ans;
    		cin >> l >> r;//好久没用过cin/cout了,庆祝一下
    		int p = l / 10000 , q = r / 10000;
    		if(p == q)
    			ans = GetMin(l , r);
    		else {
    			ans = (p + 1) * 10000;
    			minn = count(ans);
    			for(int i = ans ; i < r ; i += 10000) {//[(p+1)*1e4,(q-1)*1e4)
    				if(count(i) < minn)
    					minn = count(i) , ans = i;
    			}
    			int tmp = GetMin(l , (p + 1) * 10000);//[l,(p+1)*1e4]
    			if(count(tmp) < minn)
    				minn = count(tmp) , ans = tmp;
    				
    			tmp = GetMin(q * 10000 , r);//[q*1e4,r]
    			if(count(tmp) < minn)
    				minn = count(tmp) , ans = tmp;
    		} 
    		cout << ans << endl;
    	}
    	return 0;
    } 
    

    暴力(std.cpp)

    #include <iostream>
    using namespace std;
    int count(int x) {
    	while(x % 10 == 0)x/=10;
    	int res = (x % 10 == 5 ? -1 : 0);
    	while(x != 0) {
    		x /= 10;
    		res += 2; 
    	}
    	return res;
    }
    int main() {
    	int t;
    	cin >> t;
    	while(t--) {
    		int l ,r;
    		cin >> l >> r;
    		int minn = (1 << 29) , ans;
    		for(int i = l ; i <= r ; i++) {
    			int tmp = count(i);
    			if(tmp < minn)
    				minn = tmp , ans = i;
    		}
    		cout << ans << endl;
    	}
    	return 0;
    } 
    

    对拍用随机数生成器(random.cpp)

    #include <bits/stdc++.h>
    using namespace std;
    int random(int r , int l = 1) {
    	return r == l ? l : ((long long)rand() * rand() % (r - l) + l);
    }
    int main() {
    	srand((unsigned)time(0));
    	
    	int t = random(100);
    	cout << t << endl;
    	for(int i = 1 ; i <= t ; i++) {
    		int l = random(100000000) , r = l + random(1000000);//说明:这里是为了保证暴力程序不超时,可自行加大数据强度
    		cout << l << ' ' << r << endl;
    	}
    	return 0;
    }
    

    对拍控制

    #include <bits/stdc++.h>
    using namespace std;
    int main() {
    	while(true) {
    		system("random.exe > input.txt");
    		puts("random");
    		
    		system("std.exe < input.txt > output1.txt");
    		puts("std");
    		
    		system("tested < input.txt > output2.txt");
    		puts("tested");
    		
    		if(system("fc output1.txt output2.txt")) {
    			cout << "WA";
    			system("start input.txt");
    			return 0;
    		}
    		
    	}
    	return 0;
    }
    
  • 相关阅读:
    全网最全微服务架构—Spring Cloud详解,没有比这更详细的了!
    基于 Spring Cloud 的微服务架构实践指南(上)
    如何在一分钟内搞定面试官?
    成功面试宝典Java
    Spring Boot 自动装配流程
    C语言浮点数
    C语言字符串
    C语言数据类型转换
    C语言结构体
    C语言格式化输出
  • 原文地址:https://www.cnblogs.com/dream1024/p/14039202.html
Copyright © 2020-2023  润新知