开学第四周(习题+感悟)

(一)Arab Collegiate Programming Contest 2015

A -The Lion King

题目描述

In the Pride Lands of Africa, a lion rules over the animals as king. The birth of King Mufasa and QueenSarabi’s son Simba creates envy and resentment in Mufasa’s younger brother, Scar, who knows his nephewnow replaces him as heir to the throne.
After Simba has grown into a young cub, Mufasa gives him a tour of the Pride Lands, teaching him theresponsibilities of being a king and the circle of life. They spent the whole day in this tour and now it’stime to sleep.
As Simba is still young, he didn’t manage to sleep quickly and kept nudging his father to speak with him.Mufasa is really tired and would like to sleep so he thought of asking Simba a hard question to keep himbusy. Mufasa asked Simba how many stars are there in the sky?
Simba sees the sky as an infinite 2D grid with some glowing points.
A star is a set of ve points (p1, p2, p3, p4, and p5) satisfying these conditions:
• p1.y > p5.y
• p5.y = p2.y
• p3.y, p4.y < p5.y
• p5.x < p1.x < p2.
• p5.x < p4.x < p1.x
• p1.x < p3.x < p2.x
在这里插入图片描述Can you help Simba answer this question as soon as possible?

Input

Your program will be tested on one or more test cases. The first line of the input will be a single integerT, the number of test cases (1 ≤ T ≤ 200), followed by T test cases. The first line of each test case willcontain one integer N (5 ≤ N ≤ 5, 000) where N is the number of points in the sky.
The following N lines will each contain a pair of integers x and y separated by a single space(( -5, 000 ≤ x, y ≤ 5, 000) representing the coordinates of the points.

Output

For each test case, print one line which contains the number of stars that Simba can see in the sky modulo1,000,000,007. Each point can belong to multiple stars.

Sample Input

2
5
0 5
4 4
-4 4
2 0
-2 0
8
0 5
4 4
-6 4
2 0
-1 0
-5 4
0 12
3 0

Sample Output

1
8

理解

说出来你可能不信,6000ms的题就是可以暴力的为所欲为
其实本来也没指望能AC,就写这着试试结果过了
比起完全暴力循环,我先找到了同一行的两个点,也就是5和2
然后枚举同一行点数>=2的时候随机两个点
然后枚举y更大且x在2 5范围内的1点
然后继续枚举符合y更小且x符合范围的3 4,然后算数量就好

AC代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e4 + 7;
const double pi = acos(-1);
const int mod = 1e9 + 7;
const double eps = 1e-8;
struct node{
	int x,y;
}d[5007];

int main(){
	int cas;
	scanf("%d",&cas);
	while(cas--){
		vector<int>vx[maxn],vy[maxn];
		map<int,int> mp;
		int n;
		scanf("%d",&n);
		for(int i = 1;i <= n;i++){
			scanf("%d %d",&d[i].x,&d[i].y);
			d[i].x += 5000;
			d[i].y += 5000;
			vy[d[i].y].push_back(i);
			vx[d[i].x].push_back(i);
			mp[d[i].y] = 1;
		}
		ll ans = 0;
		vector<int>::iterator it,iter;
		map<int,int>::iterator itt;
		for(itt = mp.begin();itt != mp.end();itt++){
			int k = itt->first;
			if(vy[k].size() >= 2){
				for(int i = 0;i < vy[k].size();i++){
					for(int j = i+1;j < vy[k].size();j++){
						int t1 = d[vy[k][i]].x;
						int t2 = d[vy[k][j]].x;
						if(t1 == t2) continue;
						if(t1 > t2) swap(t1,t2);
//						cout << t1 <<" " <<t2<<endl;
						for(int l = 1;l <= n;l++){
							int cnt1 = 0,cnt2 = 0;
							if(d[l].x > t1 && d[l].x < t2 && d[l].y > k){
//								cout <<" l = " << l <<endl;
								for(int r = 1;r <= n;r++){
									if(d[r].x > t1 && d[r].x < d[l].x && d[r].y < k){
										cnt1++;
									}
									if(d[r].x < t2 && d[r].x > d[l].x && d[r].y < k){
										cnt2++;
									}
								}
								ans += cnt1 * cnt2 % mod;
								ans %= mod;
							}
						}
//						cout <<"ans = " <<ans<<endl;
					}
				}
			}			
		}
		cout << ans << endl;		
	}
	return 0;
}

B - Fractionstellar

题目描述

It’s 2050. Humans have already colonized Mars and other planets long time ago and there are alreadysome programs for travelling to the other galaxies using wormholes. Scientists are currently studying themysteries of the black holes. Their observations concluded that everything we know about physics andmathematics is completely different inside the black hole. For example, do you remember the greatestcommon divisor (GCD) and the lowest common multiple (LCM)? These functions are normally definedonly on integers. The situation is different inside the black hole; GCD and LCM are also defined onrational numbers. For two rational numbers a/b and c/d: their GCD is the greatest rational number thatdivides both numbers to an integer, and their LCM is the lowest rational number that both numbersdivide to an integer. For example, GCD(1/2, 1/3) = 1/6 and LCM(1/2, 1/3) = 1/1. Can you help thescientists in their missions solving out the mysteries of the black holes? Given two rational numbers, findtheir GCD and LCM inside the black hole.

Input

Your program will be tested on one or more test cases. The first line of the input will be a single integer T,the number of test cases (1 ≤ T ≤ 1000). Followed by T test cases. Each test case contains four integersa, b, c, and d (1 ≤ a, b, c, d ≤ 2 × 10^9) representing the two rational numbers a/b and c/d.

Output

For each test case, print a single line containing two rational numbers m/n and x/y, the GCD and theLCM of the two given rational numbers. m/n and x/y must be in their simplest form. In other words, theGCD(m,n) and GCD(x,y) must be 1.

Sample Input

2
1 2 1 3
1 5 1 7

Sample Output

1/6 1/1
1/35 1/1

理解

在CSDN上看博客get到了新知识
两个分数的最大公约数的求法:
先将两个分数都变成最简分数,将它们分母的最小公倍数作为分母
将它们分子的最大公约数作为分子,然后得到两个分数的最大公约
两个分数的最小公倍数的求法:
先将两个分数都变成最简分数,将它们分母的最大公约数作为分母
将它们分子的最小公倍数作为分子,然后得到两个分数的最小公倍数。
总结:先化为最简分数,分子与所求相同,分母与虽求相反。

分数的GCD和LCM原博客链接

AC代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 2e5 + 7;
const double pi = acos(-1);
const int mod = 998244353;
const double eps = 1e-8;
inline ll gcd(ll a,ll b){
    while(b^=a^=b^=a%=b);
    return a;
}
int main(){
	ios::sync_with_stdio(false);
	cin.tie(0),cout.tie(0);
	int cas;
	scanf("%d",&cas);
	while(cas--){
		ll a,b,c,d;
		scanf("%lld %lld %lld %lld",&a,&b,&c,&d);
		ll k1 = gcd(a,b);
		if(k1 != 1){
			a /= k1;
			b /= k1;
		}
		ll k2 = gcd(c,d);
		if(k2 != 1){
			c /= k2;
			d /= k2;
		}
		ll fm1 = b * d / gcd(b,d);
		ll fz1 = gcd(a,c);
		ll fm2 = gcd(b,d);
		ll fz2 = a* c / gcd(a,c);
		printf("%lld/%lld %lld/%lld\n",fz1,fm1,fz2,fm2);
	} 
	return 0;

C - The Minions Quiz

题目描述

The minions have finally found their new master. This time, he is a Math professor and he is trying veryhard to teach them math. He has been teaching them bitwise operators for over a year! They learnt aboutAND(&) and OR (|) operators and it is time for a quiz to test them.
The quiz is very simple, they will be given a number A of AND(&) operators, a number B of OR (|)operators and (A + B + 1) integers. They have to find the maximum number that can be obtained byinserting the & and | operators between the given nonnegative integers without changing their order.
Finally, there is a special requirement for this quiz, they are required to evaluate the operators from leftto right.

Input

The first line of the input will be a single integer T, the number of test cases (1 ≤ T ≤ 100), followedby T test cases.Each test case will consist of 2 lines. The first line will contain 2 integers A and B (0 ≤ A, B ≤ 10, 000)representing the number of AND(&) and OR (|) operators, respectively. The second line of input willconsist of (A + B + 1) 64-bit nonnegative integers separated by single spaces.

Output

For each test case, output a single line containing the maximum number that can be obtained by insertingthe operators between the given integers.

Sample Input

2
1 1
1 4 5
2 2
2 3 11 4 5

Sample Output

5
7

理解

按位与运算符(&)
参加运算的两个数据,按二进制位进行“与”运算
运算规则:0&0=0;  0&1=0;   1&0=0;    1&1=1
即:两位同时为“1”,结果才为“1”,否则为0
按位或运算符(|)
参加运算的两个对象,按二进制位进行“或”运算
运算规则:0|0=0;  0|1=1;  1|0=1;   1|1=1
 即 :参加运算的两个对象只要有一个为1,其值为1。
 所以要使得结果最大,应当是先与再或

AC代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e5 + 7;
const double pi = acos(-1);
const int mod = 998244353;
const double eps = 1e-8;
ll num[maxn];

int main(){
//	ios::sync_with_stdio(false);
//	cin.tie(0),cout.tie(0);
	int cas;
	scanf("%d",&cas);
	while(cas--){
		int a,b;
		scanf("%d %d",&a,&b);
		int k = a + b;
		for(int i = 0;i <= k;i++) cin >> num[i];
		for(int i = 1;i <= a;++i) num[0] &= num[i];
		for(int i = a+1;i <= a+b;++i) num[0] |= num[i];
		printf("%lld\n",num[0]);
	}
	return 0;
}

D - Journey

题目描述

One day, Homer was bored in his house and decided to go in a journey to discover the lands of Springfield.The lands of Springfield is an infinite grid. Homer’s house is located at cell (0, 0) and his journey consistedof N steps, where each step is either move one cell right or one cell down.
Being bored already, Homer didn’t want his journey to be boring as well. He decided he won’t move inthe same direction for more than K consecutive steps. Thus, a journey is considered to be interesting iffor each K+1 consecutive steps Homer has moved in both directions.
在这里插入图片描述
Figure 1: Example with N=5 and K=2 (first test case).
Given N and K, count the number of interesting journeys Homer can make. Two Journeys are considered different if for some i the ith step in the first Journey differs from that of the second Journey. Since the number can be large, print it modulo 1,000,000,007.

Input

Your program will be tested on one or more test cases. The first line of the input will be a single integer T, the number of test cases (1 ≤ T ≤ 500), followed by T test cases.Each test case will be presented on a single line containing two integers separated by a single space.The first integer will denote the number of steps in Homer’s journey N, followed by the second integer K representing the maximum number of consecutive steps Homer can take while moving in the same direction, where (0 ≤ N ≤ 1e5) and (0 ≤ K ≤ 1e5).Output For each test case,

Output

a single line denoting the number of different journeys Homer can make modulo1,000,000,007.

Sample Input

2
5 2
10 1

Sample Output

16
2

理解

很明显是一个递推题,超过k步就要减去直走k步的方案数
不过我取模wa了好几发

AC代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e5 + 7;
const double pi = acos(-1);
const int mod = 1e9 + 7;
const double eps = 1e-8;
ll dp[maxn],sum[maxn];

int main(){
	std::ios::sync_with_stdio(0);
	cin.tie(0);
	
	int n,k,cas;
	cin >> cas;
	while(cas--){
		cin >> n >> k;
		if(!n || !k) printf("1\n");
		else{
			dp[0] = sum[0] = 0;
			for(int i = 1;i <= n;++i){
				if(i <= k) dp[i] = (sum[i-1]+1ll)%mod;
				else dp[i] = (sum[i-1]-sum[i-1-k]+mod)%mod;
				sum[i] = (sum[i-1]+dp[i])%mod;
			}
			printf("%lld\n",((dp[n]%mod) << 1)%mod);
		}
	}
	return 0;
}

E - Road Network

题目描述

After a fierce battle with his opponent, Bruce Wayne finally won the elections and became the mayorof Gotham. Like every other politician, he had an agenda with lots of projects for the sake of Gotham’sprosperity, but he was met with the same problem, lack of fund
He decided to tackle the problem from a different perspective; he will allow companies to buyroads in the city (roads in the city are undirected). The city will get the money needed for the projectsand the companies can use the roads for advertisements (or so he thought).
After the deal was done, the companies were more cunning than he expected. They started tothreaten that they will block exactly one road in the city and prevent people from getting to their work,in the hope that people will revolt against Mayor Wayne. The problem was that the city is designed as atree of connected zones, where there is only one unique path between any two zones. Hence, blocking aroad means that some zones are not reachable from others anymore.
Mayor Wayne discussed the problem with his council and identified what they called vulnerableroads. A road is vulnerable if blocking it can disconnect two zones from each other. Mayor Wayne wantsto prevent this from happening by building more roads but his budget could afford building only oneextra road. Can you help him figure out which road he should build, such that he minimizes the numberof vulnerable roads?

Input

Your program will be tested on one or more test cases. The first line of the input will be a single integerT, the number of test cases (1 ≤ T ≤ 100) followed by T test cases. The first line of each test case willcontain one integer N, the number of zones in the city (1 ≤ N ≤ 10, 000). The following N - 1 lines willeach contain a pair of integers x and y separated by a single space (1 ≤ x, y ≤ N) which means that zonex is connected to zone y. It’s guaranteed that the edges will form a tree.

Output

For each test case, print a single line containing an integer, the minimum number of vulnerable roads inthe city after building the new road.

Sample Input

2
3
1 2
1 3
4
1 2
2 3
2 4

Sample Output

0
1

理解

其实这题不用想的很复杂,要求关键点最少,只要保证形成最大的环就好
所以dfs找一下这棵树最长的直径,然后连接直径头尾形成最大的环
n-最长直径-1就是关键点的个数

AC代码

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <vector>
using namespace std;
const int N=1e5+50;
const int M=1e6+50;
int n,u,v;
struct Edge{
    int v,next;
}edge[M];
int cnt;
int head[N],dep[N];
bool vis[N];
void init(){
    cnt=0;
    memset(head,-1,sizeof(head));
}
void addEdge(int u,int v){
    edge[cnt]=Edge{v,head[u]};
    head[u]=cnt++;
    edge[cnt]=Edge{u,head[v]};
    head[v]=cnt++;
}
//dfs方法
//dfs相当于起到一个分层的作用,层次最深的就是离根最远的点
void dfs(int u,int d){
    vis[u]=true;
    dep[u]=d;
    for(int i=head[u];i!=-1;i=edge[i].next){
        int v=edge[i].v;
        if(!vis[v]){
            dfs(v,d+1);
        }
    }
    return;
}
int main(){
    int cas;
    scanf("%d",&cas);
    while(cas--){
    	scanf("%d",&n);
	    init();
	    for(int i=0;i<n-1;i++){
	        scanf("%d%d",&u,&v);
	        addEdge(u,v);
	    }
	    memset(vis,false,sizeof(vis));
	    dfs(1,0);
	    int s=0;
	    for(int i=1;i<=n;i++){
	        if(dep[i]>dep[s]){
	            s=i;
	        }
	    }
	    memset(vis,0,sizeof(vis));
	    dfs(s,0);
	    int t=0;
	    for(int i=1;i<=n;i++){
	        if(dep[i]>dep[t]){
	            t=i;
	        }
	    }
	    printf("%d\n",n-1-dep[t]);
	}
    return 0;
}

(二)Benelux Algorithm Programming Contest 2019

A - Find my Family

题目描述

The first line contains ​, the number of photos you have to process.You are looking for a particular family photo with you and your favorite relatives Alice and Bob. Each family photo contains a line-up of n people. On the photo you’re looking for, you remember that Alice, who is taller than you, was somewhere on your left from the perspective of the photographer. Also, Bob who is taller than both you and Alice, was standing somewhere on your right.
在这里插入图片描述
Since you have a large number of family photos, you want to use your computer to assist in finding the photo. Many of the photos are quite blurry, so facial recognition has proven ineffective. Luckily, the Batch Apex Photo Classifier, which detects each person in a photo and outputs the sequence of their (distinct) heights in pixels, has produced excellent results. Given this sequence of heights for k photos, determine which of these photos could potentially be the photo you’re looking for.

Input

The first line contains1 ≤ k ≤ 1000, the number of photos you have to process.
Then follow two lines for each photo
The first line contains a single integer 3 ≤ n ≤ 3e5 , the number of people on this photo.
The second line contains n distinct integers 1 ≤ h1,h​2 ,…,hn​ ≤1e9, the heights of the people in the photo, from left to right.
It is guaranteed that the total number of people in all photos is at most 3×1e5.

Output

On the first line, output the number of photos k that need further investigation
Then print k lines each containing a single integer1 ≤ a​i ≤ n, the sorted indices of the photos you need to look at.

Sample Input

样例输入1
1
3
2 1 3
样例输入2
4
4
140 157 160 193
5
15 24 38 9 30
6
36 12 24 29 23 15
6
170 230 320 180 250 210

Sample Output

样例输出1
1
1
样例输出2
2
2
4

理解

先从后到前记录每个数之后的最大数
然后通过upperbound寻找前面比他大的数,若有则这个数是中间数

AC代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 3e5 + 7;
const double pi = acos(-1);
const int mod = 998244353;
const double eps = 1e-8;
int a[maxn],ma[maxn];
set<int> s;
vector<int> v;

int main(){
	ios::sync_with_stdio(false);
	cin.tie(0),cout.tie(0);
	int cas;
	scanf("%d",&cas);
	for(int e = 1;e <= cas;e++){
		s.clear();
		int n;
		scanf("%d",&n);
		int maxx = 0;
		for(int i = 1;i <= n;i++)
			scanf("%d",&a[i]);
		for(int i = n;i >= 1;i--){
			if(a[i] > maxx) maxx = a[i];
			ma[i] = maxx;
		}
		for(int i = 1;i <= n;i++){
			if(s.empty() || a[i] == ma[i]){
				s.insert(a[i]);
				continue;
			}
			set<int>::iterator it;
			it = s.upper_bound(a[i]);
			if(it != s.end() && *it < ma[i]){
				v.push_back(e);
				break;
			}
			s.insert(a[i]);
		}		 
	}
	printf("%d\n",v.size());
	for(int i = 0;i < v.size();i++){
		printf("%d\n",v[i]);
	}
	return 0;
}

B - Appeal to the Audience

题目描述

You are the director of the upcoming Bordfite Arena Progaming Competition. Youhave invited a bunch of players and are now setting up the matches for theknockout tournament that will determine the winner. As you may know, BordfiteArena is a game that heavily rewards skill and very little luck isinvolved. This implies that whenever any number of players play a game ofBordfite Arena, the most skilled player will always win!Hence the winner of the tournament is already known, and you are a bit worried about this.How will you appease the audience?
You embark on a short quest to find out what the audience finds interesting. Nosurprises there: people find it most interesting when they see skillful playerscompete. Whenever a match is played, the happiness the audience gets from amatch is the sum of the skill levels of the players. The total happiness the audiencegets from the tournament is the sum of the happiness obtained during allmatches. This is very useful information, because of course you want the audience to be as happy as possible at the end of the tournament.
Moreover, you invested some time to ask people what kind of knockout format theylike. It turns out that instead of the plain old binary tree for the knockoutschedule, they prefer a specific weird-looking rooted tree, and so you decide touse that. This means the final step for you to complete is to divide the playersover the leaves of the given tree so that over the entire tournament, the happiness ofthe audience is maximized.

Input

The first line contains integers 3 ≤ n ≤1e5 and 1 ≤ k ≤ n−1 , the number of nodes of the tree and the number of players. The nodes are labelled 00 through n−1, and 0 is the root of the tree.
The second line contains kk integers 0 ≤ a1 ,…,a​k ≤ 1e9,denoting the skill values of the players.
Then follow n-1 lines, the iith of which (1 ≤ i ≤ n−1) contains the parent 0 ≤ pi < i of node i.
It is guaranteed that the tree has exactly kk leaves and that there are no nodes with exactly one child.

Output

Output the maximal possible happiness the audience can obtain from this tournament.

Sample Input

样例输入1
5 3
5 4 3
0
0
1
1
样例输入2
11 7
30 5 15 1 3 100 50
0
0
1
0
2
5
2
5
5
1

Sample Output

样例输出1
17
样例输出2
454

AC代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e5 + 7;
struct node{
	int to,nxt;
	node(){}
	node(int to,int nxt):to(to),nxt(nxt){}
}edge[maxn];
int dp[maxn],h[maxn],vl[maxn],b[maxn],tot;
vector<int> vt;
void add(int u,int v){
	edge[tot] = node(v,h[u]);
	h[u] = tot++;
	return;
}
void DP(int u){
	dp[u] = 1;
	for(int i = h[u];~i;i = edge[i].nxt){
		int v = edge[i].to;
		DP(v);
		if(dp[v]+1 > dp[u]){
			dp[u] = dp[v]+1;
			b[u] = v;
		}
	}
	for(int i = h[u];~i;i = edge[i].nxt){
		int v = edge[i].to;
		if(v != b[u]) vt.push_back(dp[v]);
	}
	return ;
}
int main(){
	memset(h,-1,sizeof(h));
	tot = 0;
	int n,k;
	scanf("%d %d",&n,&k);
	int r = k;
	for(int i = 0;i < k;i++) scanf("%lld",&vl[i]);
	for(int i = 1;i < n;i++){
		int x;
		scanf("%d",&x);
		add(x,i);
	}
	DP(0);
	vt.push_back(dp[0]-1);
	sort(vl,vl+k,greater<int>());
	sort(vt.begin(),vt.end());
	ll ans = 0;
	ll len = vt.size();
	for(int i = 0;i < k;i++){
		ans += (ll)vl[i] * (ll)(vt[len-1-i]);
	}
	cout << ans <<endl;
    return 0;
}

(三)我的感想

冲冲冲

难得一周的周记居然是提前写完的,以前都是超时写的15555发现拖延症害人,作业拖了一堆没写完,这周的比赛给我打自闭了,反正能写的就是人均能A题呗,菜鸡哭泣。dp依旧是我的一生之敌,果然还是思维题都靠运气发现(那次cf)其实大佬有更简单的思路,结束后看看群大佬的写法,人看傻了。噜噜噜,好不容易蓝了的名希望别褪色。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值