zoukankan      html  css  js  c++  java
  • [noip模拟赛2017.7.17]

    模拟试题(四)

    试题概览

    题目名称 求和 序列合并 Tower
    提交文件 sum.* sequence.* tower.*
    输入文件 sum.in sequence.in tower.in
    输出文件 sum.out sequence.out tower.out
    时间限制 1s 1s 1s
    空间限制 128MB 128MB 128MB

    题目来源 Zju topcoder

    求和

    题目描述

    求 1b+2b+…+a^b 的和除以 10000 的余数

    输入格式

    第一行包含一个正整数 N 表示共有 N 组测试数据;
    接下来 N 行,每行包含两个整数 a 和 b。

    输出格式

    共 N 行,每行一个对应的答案。

    数据规模

    对于 30%的数据,满足 N<=10,a,b<=1000;
    对于 100%的数据,满足 N<=100,a,b<=1,000,000,000。

    输入样例

    1

    2 3

    输出样例

    9

    题解

    对于a>10000的情况,不拿发现

        a^b=(amod10000)^b (mod10000)
    

    所以,我们相当于只用处理10000以内的情况就行了

    #include <iostream>
    #include <cstdio>
    #include <cmath>
    #define LL long long
    using namespace std;
    const LL mod = 10000;
    LL ksm(LL x,LL y){
    	LL rtn;
    	for(rtn=1;y;y>>=1,x=(x*x)%mod)
    		if(y&1)rtn=(rtn*x)%mod;
    	return rtn;
    }
    LL N,a,b;
    int main(){
    	freopen("sum.in","r",stdin);
    	freopen("sum.out","w",stdout);
    	scanf("%lld",&N);
    	while(N--){
    		scanf("%lld%lld",&a,&b);
    		LL ans=0,sum=0;
    		LL t=a/mod;
    		LL s=a%mod;
    		for(int i=1;i<=s;i++){
    			LL rst=ksm(i,b);
    			sum=(sum+rst)%mod;
    			ans=(ans+rst)%mod;
    		}
    		if(t){
    			for(int i=s+1;i<=mod;i++){
    				LL rst=ksm(i,b);
    				sum=(sum+rst)%mod;
    			}	
    			ans=(ans+(sum*t)%mod)%mod;
    		}
    		printf("%lld
    ",ans);
    	}
    	return 0;
    }
    
    

    序列合并

    题目描述

    有两个长度都为 N 的序列 A 和 B,在 A 和 B 中各取一个数相加可以得到 N^2 个和,求这 N^2 个 和中最小的 N 个。

    输入格式

    第一行一个正整数 N;

    第二行 N 个整数 Ai,满足 Ai<=Ai+1 且 Ai<=10^9;

    第三行 N 个整数 Bi,满足 Bi<=Bi+1 且 Bi<=10^9;

    输出格式

    仅一行,包含 N 个整数,从小到大输出这 N 个最小的和,相邻数字之间用空格隔开。

    数据规模

    对于 50%的数据,满足 1<=N<=1000;

    对于 100%的数据,满足 1<=N<=100000。

    输入样例

    3

    2 6 6

    1 4 8

    输出样例

    3 6 7

    题解

    假想有n个队列,每个队列n个元素,第i个队列的第j个元素为(A[i]+B[j])
    那么显然对于每个队列,其中元素都是单调递增的,那么我们把刚开始每个队列的开头放入一个优先队列,每次弹出一个最小值(A[i]+B[j]),找到该最小值所在的队列,将下一个可能成为答案的值(A[i]+B[j+1])丢入优先队列,重复n次,总复杂度O(nlogn)

    #include <iostream>
    #include <cstdio>
    #include <cmath>
    #include <queue>
    using namespace std;
    
    int N,A[100100],B[100100],cnt;
    struct node{
    	int x,y;
    	node (int xx=0,int yy=0){
    		x=xx;y=yy;
    	}
    	friend bool operator < (node a,node b){
    		return A[a.x]+B[a.y]>A[b.x]+B[b.y];
    	}
    };
    priority_queue<node>q;
    int main(){
    	freopen("sequence.in","r",stdin);
    	freopen("sequence.out","w",stdout);
    	scanf("%d",&N);
    	for(int i=1;i<=N;i++)scanf("%d",&A[i]);
    	for(int i=1;i<=N;i++)scanf("%d",&B[i]);
    	for(int j=1;j<=N;j++)
    		q.push(node(1,j));
    	while(true){
    		cnt++;
    		node k=q.top;q.pop();
    		q.push(node(k.x+1,k.y));
    		printf("%d",A[k.x]+B[k.y]);
    		if(cnt==N)break;
    	}
    	return 0;
    }
    
    /*
    3
    2 6 6
    1 4 8
    */
    /*#include <iostream>
    #include <cstdio>
    #include <cmath>
    #include <queue>
    #include <vector>
    #define mod (10000)
    using namespace std;
    
    int N,A[100100],B[100100],cnt,ans[100100];
    struct node{
    	int x,y;
    	node (int xx=0,int yy=0){
    		x=xx;y=yy;
    	}
    	friend bool operator < (node a,node b){
    		return A[a.x]+B[a.y]>A[b.x]+B[b.y];
    	}
    };
    
    priority_queue<node>q;
    vector<int>v[100100];
    int main(){
    	freopen("sequence.in","r",stdin);
    	freopen("sequence.out","w",stdout);
    	scanf("%d",&N);
    	for(int i=1;i<=N;i++)scanf("%d",&A[i]);
    	for(int i=1;i<=N;i++)scanf("%d",&B[i]);
    	q.push(node(1,1));v[1].push_back(1);
    	while(true){
    		node k=q.top();q.pop();
    		int i=k.x,j=k.y;
    		ans[++cnt]=A[i]+B[j];
    		printf("%d ",ans[cnt]);
    		if(cnt==N)break;
    		bool find=false;
    		for(int e=0,sz=v[i].size();e<sz;e++)
    			if(v[i][e]==j+1){
    				find=true;
    				break;
    			}
    		if(!find){
    			q.push(node(i,j+1));
    			v[i].push_back(j+1);
    		}
    		find=false;
    		for(int e=0,sz=v[i+1].size();e<sz;e++)
    			if(v[i+1][e]==j){
    				find=true;
    				break;
    			}
    		if(!find){
    			q.push(node(i+1,j));
    			v[i+1].push_back(j);
    		}
    	}
    	return 0;
    }
    */
    /*
    3
    2 6 6
    1 4 8
    */
    
    

    Tower

    题目描述

    平面上有 N 个整数坐标点。如果将点(x0,y0)移动到(x1,y1),则需要的代价为|x0-x1|+|y0-y1|。 求使得 K(K=1,2,3….N)个点在同一位置上最小需要的代价。

    输入格式

    第一行包含一个正整数 N;
    接下来 N 行,每行两个正整数 xi 和 yi,为第 i 个点的坐标,不超过 10^6。

    输出格式

    共 N 行,第 i 行为使得有 i 个点在同一位置的最小代价。

    数据规模

    对于 100%的数据,满足 1<=N<=50。

    输入样例

    4

    15 14

    15 16

    14 15

    16 15

    输出样例

    0

    2

    3

    4

    题解

    本题是个暴力,外层枚举选择k个点的答案,然后枚举每一个可能成为最优值的点,计算出每个点离它的距离,然后找出最近的k个点,即为答案

    #include <iostream>
    #include <cstdio>
    #include <cmath>
    #include <algorithm>
    #include <queue>
    #define mod (10000)
    #define INF (1<<30)
    using namespace std;
    
    struct Point {
    	int x,y;
    	Point (int xx=0,int yy=0){
    		x=xx;y=yy;
    	}
    }p[100];
    int px[100],py[100];
    int N;int dis[100];
    int main(){
    	freopen("tower.in","r",stdin);
    	freopen("tower.out","w",stdout);
    	scanf("%d",&N);
    	for(int i=1;i<=N;i++){
    		scanf("%d%d",&p[i].x,&p[i].y);
    		px[i]=p[i].x;
    		py[i]=p[i].y;
    	}
    	printf("0
    ");
    	for(int k=2;k<=N;k++){
    		int ans=INF;
    		for(int i=1;i<=N;i++)
    			for(int j=1;j<=N;j++){
    				int sum=0;
    				for(int q=1;q<=N;q++)
    					dis[q]=abs(px[i]-p[q].x)+abs(py[j]-p[q].y);
    				sort(dis+1,dis+1+N);
    				for(int q=1;q<=k;q++)
    					sum+=dis[q];
    				ans=min(sum,ans);
    			}
    		printf("%d
    ",ans);
    	}
    	return 0;
    }
    /*
    4
    15 14
    15 16
    14 15
    16 15
    
    
    */
    
    
  • 相关阅读:
    简单分页案例
    layer弹出层
    layDate 日期与时间组件 入门
    error: Microsoft Visual C++ 14.0 is required. Get it with "Microsoft Visual C++ Build Tools":解决方案
    eclipse常用快捷键
    javascript DOM编程艺术(第2版)
    webstorm破解
    Intellij IDEA搭建vue-cli项目
    颜色rgba、hsla
    文本阴影、换行、溢出
  • 原文地址:https://www.cnblogs.com/Anoxiacxy/p/7201111.html
Copyright © 2011-2022 走看看