Week4 assignment

A question DDL fear

Problem Description

ZJM has n assignments, and each assignment has its own DDL. If ZJM does not complete this assignment before DDL, the teacher will deduct all the usual assignments for this assignment.
So ZJM wants to know how to arrange the order of doing homework, in order to deduct as little points as possible.
Please help him!
input: The
input contains T test cases. The first line of input is a single integer T, the number of test cases.
Each test case starts with a positive integer N (1 <= N <= 1000), indicating the number of jobs.
Then two lines. The first line contains N integers, indicating DDL, and the next line contains N integers, indicating points deducted.
output:
For each test case, you should output the smallest total reduction score, one line per test case.

Ideas

This time use a structure to store the score and ddl of each job. Take the one job with the highest score each time to see if the date before ddl is occupied. Use it if it is not occupied, otherwise discard it. Use a vis here The array indicates whether the date is occupied. Because there are multiple sets of data, it needs to be reset to 0 every time.

Code
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;

struct mm
{
	int t,v; 
	bool operator<(const mm&p)
	{
		return v>p.v;
	}
};
bool vis[1001];
mm shu[1002];
int n,T;
int main()
{
	scanf("%d",&T);
	while(T--)
	{
		memset(vis,0,sizeof(vis));
		scanf("%d",&n);
		for(int i=0;i<n;i++)
		{
			scanf("%d",&shu[i].t);
		}
		for(int i=0;i<n;i++)
		{
			scanf("%d",&shu[i].v);
		}		
		sort(shu,shu+n);
		int num=0 ;
		for(int i=0;i<n;i++)
		{
			bool flag=1;
			for(int j=shu[i].t;j>0;j--)
			{
				if(vis[j]==0)
				{
					vis[j]=1; 
					flag=0;
					break;
				}
			}
			if(flag)
				num+=shu[i].v;
		} 
		printf("%d\n",num);
	} 
	return 0;
}

to sum up

This is also a typical problem of greed,

Question B 4 series

Problem Description

ZJM has four series A, B, C, D, each series has n numbers. ZJM takes a number from each sequence, and he wants to know how many schemes make the sum of the four numbers zero. When there are multiple identical numbers in a sequence, treat them as different numbers.
Please help him!
input:
first row: n (representing the number of numbers in the sequence) (1≤n≤4000) In the
next n rows, there are four numbers in the i-th row, which represent the numbers in the sequence A, B, C, D I-th number (the number is not more than 2 to the 28th power)
output:
the number of different combinations

Ideas

The idea of ​​dichotomy can be used here. One has four arrays, and the two before and after can be combined to obtain two arrays. The number that may be 0 must be the opposite of the two arrays, as long as one of the arrays To sort, use the opposite number of each element in another array to find the first and last occurrences in this array to get the number of occurrences. The total number is the number of possible combinations.

Code
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;

int a1[4001],a2[4001],a3[4001],a4[4001]; 
int b1[16000111],b2[16000111];
int n;
int find(int t,int num)
{
	t*=-1;
	int first=-1,last=0;
	int l=0,r=num-1;
	bool f1=0;
	while(l<=r)
	{
		int mid=(l+r)/2;
		if(b1[mid]>=t)
		{
			if(b1[mid]==t)f1=1;
			first=mid;
			r=mid-1;
		}
		else l=mid+1;
	}
	l=0;
	r=num-1;	
	while(l<=r)
	{
		int mid=(l+r)/2;
		if(b1[mid]==t)
		{ 
			last=mid;
			l=mid+1;
			
		}
		else if(b1[mid]>t)r=mid-1;
		else l=mid+1;
	}
 	if(f1) {//printf("%d\n",t);
	return last-first+1;}
	else return 0;
	
}
int main()
{
	int num=0,count=0;
    scanf("%d",&n);
    for(int i=0;i<n;i++)
       	scanf("%d%d%d%d",&a1[i],&a2[i],&a3[i],&a4[i]);
    for(int i=0;i<n;i++)
		for(int j=0;j<n;j++)
		{
			b1[num]=a1[i]+a2[j];
			b2[num++]=a3[i]+a4[j];
			   }   	
	sort(b1,b1+num);
 	for(int i=0;i<num;i++)
	{
		count+=find(b2[i],num);
	}
	cout<<count<<endl;
	return 0;
}

to sum up

Alas, the evil opposite number was written when I first looked at the ppt in class, but every time I got the
wrong answer, I forgot to find the opposite number in the array, o (╥﹏╥) o

C Question DDL Fear

Problem Description

TT is a serious cat lover who indulges in the cat channel on station B every day.
One day, TT's friend ZJM decided to give TT a problem. If TT can solve this problem, ZJM will buy a cute cat and give it to TT.
The task content is, given an N number array cat [i], and use this array to generate a new array ans [i]. The new array is defined as for any i, j and i! = J, all have ans [] = abs (cat [i]-cat [j]), 1 <= i <j <= N. Try to find the median of this new array. The median is the number corresponding to the (len + 1) / 2 position after sorting, and '/' is rounded down.
TT wants to get that cute cat very much, can you help him?
input:
multiple sets of inputs, each time entering an N, indicating that there are N numbers, then enter a sequence of length N cat, cat [i] <= 1e9, 3 <= n <= 1e5
output:
the median of the new array number

Ideas

First sort the original array to calculate the range of element values ​​in the new array. In this range, the binary answer finds a P, where P is the median. For each P, calculate the rank of P in the new sequence.
Because the original number sequence is sorted, you can go to the absolute value, get Xj <= Xi + P, enumerate the subscript i and then calculate the number of subscript j that meets the condition. The calculation here also uses binary search to find the first greater than or equal to The position of the number of Xi + P, and the sum of all the j that meets the condition is the logarithm of the binary tuple that meets the condition. Compare the number and the rank of the median. If the rank is less than the median, the median is on the right. On the side, if the rank is greater than the median, the median is on the left, and the range of the new array element value is updated accordingly. If the two numbers are equal, the P is the median.

Code
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;

int cat[100001];
int n;
int find(int t )
{ 
	int l=0,r=n-1,ans=-1; 
	while(l<=r)
	{
		int mid=(l+r)/2;
		if(cat[mid]>=t)
		{ 
			ans=mid;
			r=mid-1;
		}
		else l=mid+1;
	}
	return ans;
}
 
int main()
{
 	while(scanf("%d",&n)!=EOF)
 	{
 		for(int i=0;i<n;i++)
 		scanf("%d",&cat[i]);
 		sort(cat,cat+n);
 		int l=0,r=cat[n-1]-cat[0],ans=0;
 		int zh=(n*(n-1)/2+1)/2;
		  while(l<r)
        {
			//int mingci=0;
            int mid = (l+r)/2;
            int mingci = 0;
            for(int i=0;i<n;i++)
            {
                int rr = find(cat[i]+mid);//小于mid的个数 
                if(rr!=-1)
                mingci+= (n-rr);//计算mid名次 
            }
            if(mingci>(n*(n-1)/2-zh))//寻找第一个0出现 
            {
                ans = mid;
                l = mid +1;
            }
            else r = mid;
        } 
        cout<<ans<<endl;
	 }
	return 0;
}
to sum up

At first I did n’t understand too much about the ideas given in the PPT for the first time. Afterwards, I thought about it for a long time before I understood the specific meaning.

Published 20 original articles · praised 3 · visits 456

Guess you like

Origin blog.csdn.net/qq_44893580/article/details/104979462