Week4- jobs

Fear of DDL - A


Meaning of the questions:

ZJM there are n jobs, each job has its own DDL, if ZJM not done the job before the DDL, then the teacher will deduct this job all the usual points.
So ZJM want to know how to arrange the order of homework to buckle a bit less points as possible.
Please help him!

Input:

Input of T test. The first input line is a single integer T, was found in the number of test cases.
Each test case to begin a positive integer N (1 <= N <= 1000), indicates the number of jobs.
Then two lines. The first line contains N integers representing the DDL, the next row containing N integers representing buckle points.

output:
For each test case, you should reduce the output of the minimum total score, each test line.


Ideas:

This is a greedy algorithm known exercises, greedy indicators need to find out the problem. Each ddl completion time is 1, giving priority to high-scoring job. This time needs to be sorted in descending score, if the score is the same, then consider ddl, ddl the same score from lowest to highest. ddl score score and may constitute a structure. Find a greedy indicators, it is for the i-th ddl, use an array of bool whether the time has been utilized, according to t traverse from front to back, once the idle time to find the time schedule.


to sum up:

This question is only beginning to consider ordering the score after the same score did not consider the need for further sorting, although the sample passed, but still the wa. For greedy indicators it must be considered serious for certain circumstances need to justify the same.


Code:

#include<iostream>
#include<algorithm>
#include<queue>
#include<cstring>
using namespace std;
#define _for(i,a,b) for(int i=a;i<b;i++)

struct ZJM
{
	int ddl;
	int score;
}z[1010];
bool vis[1010] = { false };
int cmp(const ZJM z1, const ZJM z2)
{
	if (z1.score == z2.score)
		return z1.ddl < z2.ddl;
	return z1.score > z2.score;

}

int main()
{
	int T,n;
	int a;
	cin >> T;
	_for(i, 0, T)
	{
		int count = 0;
		int a;
		cin >> n;
		_for(i, 0, n)
		{
			cin >> z[i].ddl;
		}
		_for(i, 0, n)
		{
			cin >> z[i].score;
		}
		sort(z, z + n,cmp);
		memset(vis, 0, sizeof(vis));
		_for(i, 0, n)
		{
			for (a = z[i].ddl; a >= 1; a--)
			{
				if (vis[a] == false)
				{
					vis[a] = true;
					break;
				}
			}
			if (a == 0) count += z[i].score;
		}
		cout << count << endl;
	}
	return 0;
	
}

B - four columns

Meaning of the questions:

ZJM has four columns A, B, C, D, each column has the number of digits n. ZJM a number taken from each respective column number, he would like to know how many kinds of programs such that the number of 4 and 0.
When a number of columns has the same plurality of numbers, to treat them as a different number.

Input:
First line: n (number representative of the number of columns) (1≤n≤4000)
the next n-th row, the i-th row of four numbers, each number of columns A, B, C, D of the i-th digit (digit 2 to the power of not more than 28)

output:
output number of different combinations.


Ideas:

Seniors spoken by a start, the number of A + enumerator columns columns B, then the number of columns enumerate the number of columns C + D. Then inverse of C + D is calculated how many times appeared in the A and B. But writing code or accidentally complexity is O (N ^ 4)

_for(i, 0, n*n)
	{
		_for(j, 0, n * n)
		{
			if (sumab[i] == -sumcd[j])
				count++;
		}
	}

Obviously, certainly TE, this time considering the dichotomy method to reduce the complexity, the first is to enumerate the number of columns to save all the data C + D array sumcd from small to large, and then enumerate the sumab turn, initialization start and End, the start is 0, end of (n-1) * (n-1), then use two hours, sumab [i] is compared with sumcd [mid], to find the sum is equal to the minimum position 0, then again circulation, because sumcd is ordered, if the same number appears more than once, add up to the right has been so complete traversal sumab to get in line with the number.

Code:

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
#define _for(i,a,b) for(int i=a;i<b;i++)
#define MAXN 4000
int a[MAXN], b[MAXN], c[MAXN], d[MAXN],sumab[MAXN*MAXN],sumcd[MAXN*MAXN];
int main()
{
	int count = 0;
	int n;
	cin >> n;
	_for(i, 0, n)
	{
		cin >> a[i] >> b[i] >> c[i] >> d[i];
	}
	int k = 0;
	for (int i = 0; i < n; i++)
	{
		for (int j = 0; j < n; j++)
		{
			sumab[k] = a[i] + b[j];
			sumcd[k] = c[i] + d[j];
			k++;
		}
	}
	sort(sumcd, sumcd + k);
	for (int i = 0; i <k; i++)
	{
		int start =0, end =k-1;
		while (start < end)
		{
			int mid = (start + end) >> 1;
			if (sumab[i] + sumcd[mid] >= 0) 
			{
				end = mid;
			}
			else start = mid + 1;
		}
		while (sumab[i] + sumcd[start] == 0 && start < k)
		{
			count++;
			start++;
		}
	}
	cout << count << endl;
	return 0;

}

TT mystery gift

Meaning of the questions:

SUMMARY is given array cat [i] a number N, and generate a new array ans [i] with the array. It is defined as the new array for any i, j and i = j, are ans [] = abs (cat [i] - cat [j])!, 1 <= i <j <= N. This new array. Determine the median, then the median is the sort (len + 1) / 2 corresponding to the position number, '/' is a rounding.

Input:
multiple sets of inputs, each input one N, expressed the number N, then a length of the input sequence of the cat N, cat [i] <= 1e9 , 3 <= n <= 1e5.

output:
Output new array ans median.


Ideas:

The cat array in ascending order, the median ranking is more known with the median ranking every two minutes to give ranking (n * (n-1) / 2 + 1) / 2 pairs, if the rank is less than the median, on behalf of this number is smaller than the median, otherwise it is larger than the median. Then find the two goal value P, and then seek ranking. Ans array elements are cat [j] -cat [i] (i <j), then becomes is the desire to meet the cat [j] -cat [i] <= P for all tuples of numbers. By transposition, to give cat [j] <= P + cat [i], and then they enumerate the number j satisfying i, to obtain the ranking. Then the ranking is the use of binary search, the last meet a cat [j]> = P + CAT position [i], the maximum value of j is obtained; each j rank equal to the maximum accumulated and subtracted i. And then calculated the median ranking ranking comparison, until you find the median line.

to sum up:

1. This question is about the comparison, due to the twice-half, when the first round of bipartite want to look online there are no more practical function dichotomy: So I found this
(1), binary_search (beg, end, val )
returns a bool variable, in the manner of binary search to find val between [beg, end], returns true find, can not find the returns false.
(2), lower_bound (beg, end, val)
returns an iterator pointing non-decreasing sequence [first, last) first is greater than or equal (> =) position val.
(3), upper_bound (beg, end, val)
returns an iterator pointing non-decreasing sequence [first, last) is greater than the first one (>) position val.
Original link: https: //blog.csdn.net/xzymmd/article/details/83902281
These are the use of half to find the location. By the principle of these functions and let me know how the secondary half.
2. Due to time limit, beginning with cin resulting in multiple TE, looking for a good few times I thought it was half the reason, changes a bit, or TE, then tried it passed the scanf.
Here Insert Picture Description
Later, ask the friend learned ios :: sync_with_stdio (false) can improve the efficiency of cin.
This question is short, so I benefited a lot, learned a lot of practical knowledge.

Code:

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

int main()
{
	int n;
	int start, end, mid, median, rank,mid1,ans,ans1;
	while (cin >> n)
	{
		int cat[100002];
		for (int i = 0; i < n; i++)
		{
			scanf("%d",&cat[i]);
		}
		sort(cat, cat + n);
		ans=-1;
		start = 0;  //绝对值最小只为0
		end = cat[n - 1] - cat[0]; //最大的数
		median = (1 + n * (n - 1) / 2) / 2; //中位数所在位置
		while (start <= end)
		{
			mid = (start + end) / 2;
			rank = 0;  //初始化位置
			for (int i = 0; i < n; i++)
			{
				int temp=cat[i] + mid; 
				int l = 0, r = n-1;
				ans1=-1;
				while (l <= r)
				{
					mid1 = (l + r)/2;
					if (cat[mid1] <= temp)
					{
						ans1=mid1;
						l=mid1+1;
					}

					else r = mid1 - 1;
				}
				if(ans1!=-1)
					rank+=ans1-i;
			}
			if(rank<median)
			{
				start=mid+1;
			}
			else
			{
				ans=mid;
				end=mid-1;
			}
			
			
		}
		cout << ans << endl;

	}

	return 0;
}

Released seven original articles · won praise 0 · Views 125

Guess you like

Origin blog.csdn.net/weixin_44465341/article/details/104950977