想法题+思路(zjnu training for 神牛)

来源:互联网 发布:大学生网络惨案 编辑:程序博客网 时间:2024/05/17 20:10

A. Mafia
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

One day n friends gathered together to play "Mafia". During each round of the game some player must be the supervisor and other n - 1people take part in the game. For each person we know in how many rounds he wants to be a player, not the supervisor: the i-th person wants to play ai rounds. What is the minimum number of rounds of the "Mafia" game they need to play to let each person play at least as many rounds as they want?

Input

The first line contains integer n (3 ≤ n ≤ 105). The second line contains n space-separated integers a1, a2, ..., an (1 ≤ ai ≤ 109) — thei-th number in the list is the number of rounds the i-th person wants to play.

Output

In a single line print a single integer — the minimum number of game rounds the friends need to let the i-th person play at least airounds.

Please, do not use the %lld specifier to read or write 64-bit integers in С++. It is preferred to use the cincout streams or the %I64dspecifier.

Sample test(s)
input
33 2 2
output
4
input
42 2 2 2
output
3
Note

You don't need to know the rules of "Mafia" to solve this problem. If you're curious, it's a game Russia got from the Soviet times:http://en.wikipedia.org/wiki/Mafia_(party_game).


这道题卡了我好久,果然是思路问题吗,好吧,其实我发现了这是一道数学题。首先我们知道有n个人,然后我们设m为最少的游戏次数。然后就可以得出了n*m就是n个人如果都满足他们每个人的条件的话要总共进行几次。

然后我们要把每个人的愿望次数求出来,也就是求总和,然后就得到了一个数学公式: n*m-sum>=m ,我们的目的就是要求出最小的m使得这个式子成立。

#include<stdio.h>#include<string.h>#define maxn 111111__int64 a[maxn];int main(){int n;scanf("%d",&n);__int64 sum=0,max1=-1;for(int i=0;i<n;i++){scanf("%d",&a[i]);sum+=a[i];if(a[i]>max1) max1=a[i];}__int64 ans=0;if(sum%(n-1)) ans=sum/(n-1)+1;else ans=sum/(n-1);printf("%I64d\n",ans>max1?ans:max1);}
我一开始还是找错方向了,我尝试着写几组数据然后来找出规律,但是其实这是一道与数学有关的题,只要推出公式来就好了。


B. Fixed Points
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

A permutation of length n is an integer sequence such that each integer from 0 to (n - 1) appears exactly once in it. For example, sequence [0, 2, 1] is a permutation of length 3 while both [0, 2, 2] and [1, 2, 3] are not.

A fixed point of a function is a point that is mapped to itself by the function. A permutation can be regarded as a bijective function. We'll get a definition of a fixed point in a permutation. An integer i is a fixed point of permutation a0, a1, ..., an - 1 if and only if ai = i. For example, permutation [0, 2, 1] has 1 fixed point and permutation [0, 1, 2] has 3 fixed points.

You are given permutation a. You are allowed to swap two elements of the permutation at most once. Your task is to maximize the number of fixed points in the resulting permutation. Note that you are allowed to make at most one swap operation.

Input

The first line contains a single integer n (1 ≤ n ≤ 105). The second line contains n integers a0, a1, ..., an - 1 — the given permutation.

Output

Print a single integer — the maximum possible number of fixed points in the permutation after at most one swap operation.

Sample test(s)
input
50 1 3 4 2
output
3
这道题的大致意思是:就是给你n个数,然后让你判断那个数的数值和下标相同的个数有几种,其中你只有一次交换其中两个数字的机会,然后问你最大的满足条件的数有几个?

#include<stdio.h>#include<string.h>#define maxn 111111int a[maxn],par[maxn],vis[maxn];int main(){int n,num=0;scanf("%d",&n);for(int i=0;i<n;i++){scanf("%d",&a[i]);if(a[i]==i) num++; par[a[i]]=i;vis[a[i]]=1;}bool ff=false;for(int i=0;i<n;i++){if(a[i]!=i){if(par[i]==a[i]) {num+=2; ff=true; break;}}if(ff) break;}if(!ff){bool fa=false;for(int i=0;i<n;i++){if(vis[i]&&a[i]!=i) {fa=true; break;}}if(fa) num++;}printf("%d\n",num);}
我的想法是:分别用par数组来标记那个数的数值所对应的下标是多少,然后判断的时候就只要判断par[i]是否等于a[i]就好了。

这里的vis数组是为了标记万一后面没有与之相对应的数字可以交换的话,那么我们就只能任意交换两个了。那么vis的作用就是判断那个数是否存在的。

这里如果还是不理解的话:可以参考这一组样例:

5

1 1 1 1 1 

输出应该是1,但是若没有判断过的话,那么就会错。


A. Difference Row
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

You want to arrange n integers a1, a2, ..., an in some order in a row. Let's define the value of an arrangement as the sum of differences between all pairs of adjacent integers.

More formally, let's denote some arrangement as a sequence of integers x1, x2, ..., xn, where sequence x is a permutation of sequencea. The value of such an arrangement is (x1 - x2) + (x2 - x3) + ... + (xn - 1 - xn).

Find the largest possible value of an arrangement. Then, output the lexicographically smallest sequence x that corresponds to an arrangement of the largest possible value.

Input

The first line of the input contains integer n (2 ≤ n ≤ 100). The second line contains n space-separated integers a1a2...an(|ai| ≤ 1000).

Output

Print the required sequence x1, x2, ..., xn. Sequence x should be the lexicographically smallest permutation of a that corresponds to an arrangement of the largest possible value.

Sample test(s)
input
5100 -100 50 0 -50
output
100 -50 0 50 -100 
Note

In the sample test case, the value of the output arrangement is (100 - ( - 50)) + (( - 50) - 0) + (0 - 50) + (50 - ( - 100)) = 200. No other arrangement has a larger value, and among all arrangements with the value of 200, the output arrangement is the lexicographically smallest one.

Sequence x1, x2, ... , xp is lexicographically smaller than sequence y1, y2, ... , yp if there exists an integer r (0 ≤ r < p) such thatx1 = y1, x2 = y2, ... , xr = yr and xr + 1 < yr + 1.


这道题,额,大家都说是水题,但是我又卡了很久,好吧,难道是思维方式不同。。

这题我与正确的思路失之交臂,原来我推出来了就是 其实就只与 x1-xn 有关,所以实质就只要改变中间的就好了,中间的话直接sort一遍,然后输出,注意第一个与最后一个的值要进行换过的。

#include<stdio.h>#include<string.h>#include<iostream>#include<algorithm>using namespace std;#define maxn 111int a[maxn],c[maxn];int main(){int n,l1,l2; l1=l2=0;scanf("%d",&n);for(int i=0;i<n;i++){scanf("%d",&a[i]);c[i]=a[i];}sort(c,c+n);printf("%d ",c[n-1]);for(int i=1;i<n-1;i++) printf("%d ",c[i]);printf("%d\n",c[0]);}

虽然说还是不够好,但是想法是慢慢的积累的,而且我也能感受到自己实质性慢慢的进步,继续前行,hades!


1 0