清北学堂 2017-10-01



Problem 1. alien
Input file: alien.in
Output file: alien.out
Time limit: 1s
Memory limit: 128M
小Y 最近正在接受来自X3 星球的外星人的采访。在那个星球上,每个人的名字都是一个正整数。
所有在这个星球上的居民都是相互认识的。两个这个星球上的人的友谊值可以⽤这样来计算: 先把两个人
的名字转换成二进制,然后把他们上下对齐排好,如果同一列的值相等,那么相应列的值就是0,否则的
话就是1,结果最后仍旧转换成十进制数。(即Xor 操作)
例如,两个人的名字是19 和10,他们的友谊值是25
这个星球的价值是这么计算的: 所有友情值的和。小Y 邀请你帮助他来计算这个值。

 

Input
输入文件第一行一个整数N, 表示这个星球上的总人数。
接下来N 行,每行一个正整数,表示每个居民的姓名。
Output
输出文件一行个整数,表示这个星球的价值。
Example

alien1.in

2

19

10

alien1.out

25

alien2.in

3

7

3

5

alien2.out

12

alien3.in

5

9

13

1

9

6

alien3.out

84

Scoring
• 对于40% 的数据,N<=5000。
• 对于70% 的数据,N<=100000。
• 对于100% 的数据,N<=1e6, 每个居民的姓名小于1e6。

 

解析:

大概就是每两个数按位或一下

but我没看懂标程

 

#include
  
  
   
   
#include
   
   
    
    
#include
    
    
     
     
using namespace std;

long long n,name[1000005];
long long sum;

int main()
{
//	freopen("alien.in","r",stdin);
//	freopen("alien.out","w",stdout);
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
		scanf("%d",&name[i]);
	for(int i=1;i<=n;i++)
		for(int j=i+1;j<=n;j++)
			sum+=(long long)name[i]^(long long)name[j];
	cout<
     
     
      
      
#include 
      
      
        using namespace std; long long n,i,x,j,k,ans,a[32]; int main() { // freopen("alien.in","r",stdin); // freopen("alien.out","w",stdout); cin>>n; for (i=1;i<=n;++i) { scanf("%I64d",&x); j=0; while (x>0) { j++; a[j]=a[j]+x%2; x=x/2; } if (j>k) k=j; } for (i=k;i>=1;--i) ans=ans*2+a[i]*(n-a[i]); cout< 
        
      
     
     
    
    
   
   
  
  
 

 

Problem 2. polyline
Input file: polyline.in
Output file: polyline.out
Time limit: 1s
Memory limit: 128M
有若干个类似于下面的函数:

定义n 个函数y1(x); :::; yn(x) 的对于任意x 的总和s(x) = y1(x) + ::: + yn(x),很容易发现s(x) 的
图象是多段线组成。给你n 个函数,你的任务是找出s(x) 图象不等于180 度的角的个数。

Input
第一行一个整数n,表示函数的个数。
接下来n行, 每行包含两个空格隔开的整数ki; bi, 表示第i 个函数的参数。
Output
输出一行一个整数, 表示形成的多段线的图像中不等于180 度角的个数。

Example

polyline1.in

1

1 0

polyline1.out

1

polyline2.in

3

1 0

0 2

-1 1

polyline2.out

2

polyline3.in

3

-2 -4

1 7

-5 1

polyline3.out

3

Scoring
• 对于30% 的数据,n<=3000。
• 对于100% 的数据,1<=n<=1e5;-1e9<=ki; bi<=1e9。

 

解析:

图像只有x轴上半部分的图像

就是算一下斜率,看看与x轴夹角是否为180°

k==0的不起作用,可忽略不计

由于交点横坐标可能无法整除,因此可以

1.全部求完后判断差值是否<=1e-18,如果是,则ans--

2.让k、b分开存,约到最简比,然后看是否相同

 

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;

int n,cnt=0;
int k[100005],b[100005];
long double p[100005];

int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
	{
		int kk,bb;
		scanf("%d %d",&kk,&bb);
		if(kk)
		{
			cnt++;
			k[cnt]=kk;
			b[cnt]=bb;
			p[cnt]=-(long double)b[cnt]/(long double)k[cnt];
		}
	}
	sort(p+1,p+1+n);
	int ans=cnt;
	for(int i=1;i<=cnt;i++)
	if(p[i]-p[i-1]<=-1e18) ans--;
	printf("%d",ans);
	return 0;
}

 

Problem 3. roadwork
Input file: roadwork.in
Output file: roadwork.out
Time limit: 1s
Memory limit: 512M
现在有一条单个车道的路,两边会不断有车来,任意时刻路上只能有一个方向的车,每辆车速度相
同,同一方向的车必须在前⼀辆车上路3 秒后才能上路,可以在路⼜等待,不能超车,每个人在路口等
过其忍受范围后便会不高兴,现在请你安排过路顺序,使得不高兴的人数最少。
Input
第一行两个整数t 和n,代表有n 辆车,每辆车过桥时间为t 秒
下面n行,述每辆车,每行一个字符c,两个数字a 和r;
c=“E”或“W”代表方向,a 代表到达时间(秒),r 代表最示忍受时间(秒,上路时间- a),按到来顺序
给出,a 相同时以到来顺序为准。

Output
输出一行一个整数,代表最少发怒人数。
Example

roadwork1.in

8 3

W 10 0

W 10 3

E 17 4

roadwork1.out

roadwork2.in

100 5
W 0 200
W 5 201
E 95 1111
E 95 1
E 95 11

roadwork2.out

1

Scoring

• 对于100% 的数据,4<=t<=180; 1=<n<= 250; 0=< a < 86400; 0=<r<=3600

 

解析:

一道dp题

 

// Solution of problem Road Work
// Time complexity: O(n^3)
// Space complexity: O(n^3)
// Author: Fredrik Svensson

f[i][j][k][0/1]
temp=f[i][j][k][0/1]
f[i+1][j][tk][0]=temp+3;
if(temp+3<=r[i+1])
tk=k;
else tk=k+1;
f[i][j+1][tk][0]=temp+t;
if(temp+t<=r[i+1])
tk=k;
else tk=k+1;


#include <cstring>
#include <iostream>
#include <string>
#include <vector>
#include <cstdio>
using namespace std;

#define MAX_N 350
int resetValue = 123*MAX_N;
const int maxTotalTime = 86400+MAX_N*3+2*MAX_N*180;

struct Car
{
	int arrival;
	int lastLeave;
};
vector<Car> toWest;
vector<Car> toEast;
int timeToPass;

int dp[MAX_N+1][MAX_N+1][MAX_N+1][2]; // totalTime = dp[drivenEast][drivenWest][numIrritated][lastToWest=0,lastToEast=1]

int calc(int drivenWest, int drivenEast, int numIrritated, int lastToEast)
{
	int &dpv = dp[drivenWest][drivenEast][numIrritated][lastToEast];
	if (dpv == 0x7f7f7f7f)
	{
		if ((lastToEast ? drivenEast : drivenWest) == 0)
			dpv = maxTotalTime;
		else
		{
			const Car &myCar = (lastToEast ? toEast[drivenEast-1] : toWest[drivenWest-1]);
			if (lastToEast)
				--drivenEast;
			else
				--drivenWest;
			dpv = maxTotalTime;
			// Check with one less to the east and one less to the west.
			for (int dir = 0; dir < 2; ++dir)
			{
				// Allow getting irritated
				if (numIrritated > 0)
					dpv = min(dpv, calc(drivenWest, drivenEast, numIrritated-1, dir) + (dir == lastToEast ? 3 : timeToPass));
				// Not getting irritated
				int myTime = calc(drivenWest, drivenEast, numIrritated, dir) + (dir == lastToEast ? 3 : timeToPass);
				if (myTime <= myCar.lastLeave)
					dpv = min(dpv, myTime);
			}
			if (dpv < maxTotalTime)
				dpv = max(myCar.arrival, dpv);
		}
	}
	return dpv;
}

int main()
{
	freopen("roadwork.in","r",stdin);
	freopen("roadwork.out","w",stdout);
	int n;
	cin >> timeToPass >> n;
	for (int i = 0; i < n; ++i)
	{
		string d;
		int maxStillTime;
		Car car;
		cin >> d >> car.arrival >> maxStillTime;
		car.lastLeave = car.arrival + maxStillTime;
		if (d == "W")
			toWest.push_back(car);
		else if (d == "E")
			toEast.push_back(car);
		else
			return -1;
	}
	// Dynamic programming
	// Reset
	memset(&dp[0][0][0][0], 0x7f7f7f7f, sizeof(dp));
	dp[0][0][0][0] = dp[0][0][0][1] = -3;//???
	// Run
	int numIrritated;
	for (numIrritated = 0; numIrritated <= n; ++numIrritated)
	{
		int t = min(
			calc((int)toWest.size(), (int)toEast.size(), numIrritated, 0),
			calc((int)toWest.size(), (int)toEast.size(), numIrritated, 1));
		if (t < maxTotalTime)
			break;
	}
	cout << numIrritated << endl;
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值