오늘의 헤드 라인 필기 시험

 

목차

요소를 찾으려면 2017 년 4 월 18 일 질문 A?

2017 년 4 월 18 일 질문 B에 대한 DAU 통계

2017 년 4 월 18 일 질문 C : 공식화 된 공식

2017 년 4 월 18 일 작업 실행 전략에 대한 질문 D

2017 년 필기 시험 문제?


요소를 찾으려면 2017 년 4 월 18 일 질문 A?

이야기:

내 코드 (테스트 케이스의 100 % 통과) :

#include <iostream>
#include<algorithm>
using namespace std;
 
int l[100000], m;
 
bool find(int k)
{
	int low = 0, high = m - 1, mid;
	while (low < high - 1)
	{
		mid = (low + high) / 2;
		if (l[mid] == k)return true;
		if (l[mid] > k)high = mid;
		else low = mid;
	}
	if (l[low] == k || l[high] == k)return true;
	return false;
}
 
int main()
{
	int  n, k;
	scanf("%d", &m);
	for (int i = 0; i < m; i++)scanf("%d", &l[i]);
	sort(l, l + m);
	scanf("%d", &n);
	while (n--)
	{
		scanf("%d", &k);
		if (find(k))printf("%d ", k);
	}
	return 0;
}

 

2017 년 4 월 18 일 질문 B에 대한 DAU 통계

제목 설명 :
DAU (일일 활성 사용자 수)는 제품 성능을 측정하는 중요한 지표입니다.
주어진 날짜에 N 개의 액세스 레코드를 기반으로 해당 날짜의 총 사용자 수 M을 계산하는 프로그램을 작성해야합니다.
각 사용자는 여러 번 방문 할 수 있습니다.
편의를 위해 숫자 (uid)를 사용하여 각 사용자를 고유하게 식별합니다.

입력

각 줄에는 uid가 포함되어 있으며 0을 만나면 입력이 끝난 것으로 간주됩니다.
입력에는 총 N + 1 줄이 포함되어있어 무질서한 것으로 간주 될 수 있습니다.


숫자를 출력 합니다 : 중복 제거 후의 uid 수 M.

샘플 입력

12,933
111,111
59,220
69,433
59,220
111,111
0

샘플 출력
4

 

 

내 코드 (테스트 케이스의 100 % 통과) :

#include <iostream>
#include<set>
using namespace std;
 
int main()
{
	set<long long>se;
	se.clear();
	long long uid;
	int M;
	while (scanf("%lld", &uid))
	{
		if (uid == 0)break;
		se.insert(uid);
	}
	cout << se.size();
	return 0;
}

이 토픽은 세트의 사용이 매우 간단하고 세트의 삽입 (검색)이 로그 타임이기 때문에 효율성이 매우 높습니다.

 

2017 년 4 월 18 일 질문 C : 공식화 된 공식

제목 설명 :
다음과 같은 형식화 된 숫자가 있습니다.
  * *** *** * * *** *** *** *** *** ***
  * * * * * * * * * * * * * *
  * *** *** *** *** *** * *** *** * *
  * * * * * * * * * * * * *
  * *** *** * *** *** * *** *** ***
(* 아래 사진은 참고 용으로 첨부)

이들은 각각 12 34 5678 9 0을 나타내며
다음과 같은 형식 기호를가집니다.
   * * * * ****
  *** *** * *
   * * * * **** **
                              **
( * 아래 사진은 참고 용으로 첨부)

각각은 +-* / = 소수점을 의미합니다.
입력
이제 공식을 입력하십시오.
출력 공식
을 계산하여 위에서 언급 한 공식적인 방식으로 출력 해야합니다.
각 숫자와 기호 사이에는 두 개의 공백이 있습니다.
균등하게 나눌 수없는 경우 , 소수점 두 자리를 유지하십시오.

샘플 입력
10 + 31
샘플 출력
* *** *** * * * *
* * * * * * **** * * *
* * * *** * *** *
* * * * * * **** * *
* *** *** * * *
(* 아래 사진은 참고 용으로 첨부)

힌트
샘플 입력 2 :  
2 / 5
샘플 출력 2 :
*** *** *** * *
  * * * **** * * * *
*** * *** * * ***
* * * * *** * * ** *
*** *** *** ** *
(* 아래 사진은 참고 용으로 첨부)

데이터 범위 :
데이터 입력 숫자 및 계산 결과의 20 %는 한 자리 숫자입니다.
100 % 데이터는 입력 된 숫자와 답변이 10000 미만
임을 보장합니다. 100 % 데이터는 입력 숫자가 소수로 나타나지 않음을
보장합니다. 80 % 데이터는 계산 결과를 보장합니다. Decimal 표시되지 않습니다

내 코드 (테스트 케이스의 80 % 통과) :

#include <iostream>
#include<string.h>
using namespace std;
 
char ans[5][100], char0 = '0';
const char cs[17] = "1234567890+-*/.=";
const char s[5][100] = {
	"*    ***  ***  * *  ***  ***  ***  ***  ***  ***                                 ",
	"*      *    *  * *  *    *      *  * *  * *  * *   *        * *    *       ****  ",
	"*    ***  ***  ***  ***  ***    *  ***  ***  * *  ***  ***   *    *              ",
	"*    *      *    *    *  * *    *  * *    *  * *   *        * *  *    **   ****  ",
	"*    ***  ***    *  ***  ***    *  ***  ***  ***                      **         "
};
 
void add(char c)
{
	int k = -1, num = 5;
	for (int i = 0; i < 16; i++)if (cs[i] == c)k = i;
	if (k == -1)return;
	if (k == 15)num = 6;
	if (k == 0)num = 3;
	if (k == 14)num = 4;
	for (int i = 0; i < 5; i++)strncat(ans[i], s[i] + k * 5, num);
}
 
void add(int n)
{
	if (n >= 10)
	{
		add(n / 10);
		add(n % 10);
		return;
	}
	add(char(char0 + n));
}
 
void add(double x)
{
	int n = int(x);
	double eps = 0.0000001, r = x - n;
	if (n - x < eps && x - n < eps)r = 0;
	add(n);
	if (r == 0)return;
	add('.');
	n = int(r * 100);
	if (n % 10 == 0)n /= 10;
	add(n);
}
int main()
{
	for (int i = 0; i < 5; i++)ans[i][0] = '\0';
	int a, b, r1;
	double r2 = -1;
	char ch = ' ';
	scanf("%d %c %d", &a, &ch, &b);
	add(a);
	add(ch);
	add(b);
	add('=');
	if (ch == '+')r1 = a + b;
	if (ch == '-')r1 = a - b;
	if (ch == '*')r1 = a*b;
	if (ch == '/')r2 = a*1.0 / b;
	if (r2 == -1)add(r1);
	else add(r2);
	for (int i = 0; i < 5; i++)cout << ans[i] << endl;
	return 0;
}

 

이 코드는 잘 작성된 것 같지만 왜 80 % 만 통과하는지 모르겠습니다. void add (double x) 함수에 문제가있을 것이고 소수점 부분이 제대로 처리되지 않습니다.

먼저 모든 문자를 cs로 저장하고 해당하는 모든 형식 기호를 s에 저장하면 훨씬 쉽게 프로그래밍 할 수 있습니다.

둘째, 추가는 세 번 다시로드되고 서로 호출되어 프로그래밍이 훨씬 쉬워졌습니다.

 

2017 년 4 월 18 일 작업 실행 전략에 대한 질문 D

제목 설명 :
메소에 작업 배치가 있습니다. 이 작업 일괄 처리는 다른 작업에 의존하지 않거나 정확히 두 작업에 의존해야하며 전체 종속성 관계는 삼각형 모델을 형성합니다.
 
Job (1, 1)
Job (2, 1) Job (2, 2)
Job (3, 1) Job (3, 2) Job (3, 3)
……
Job (n, 1) Job (n, 2) …… Job (n, n)
 
위와 같이 Job (1, 1)은 Job (2, 1) 및 Job (2, 2), Job (2, 2)는 Job (3, 2) 및 Job (3, 3)에 종속됩니다 .1 <= i <n, 1 <= j <= n, Job (i, j)는 Job (i + 1, j) 및 Job (i + 1, j + 1)에 따라 다릅니다. 마지막 줄의 작업에는 작업 종속성이 없습니다.
이 작업 배치에는 특성이 있으며 각 작업은 종속 된 작업과 함께 실행되어야합니다. 즉, 작업은 다음 조건 중 하나 이상이 충족되는 경우에만 특정 실행에 대해 유효합니다.
1. 작업이 다른 작업에 의존하지 않음
2. 작업이 의존하는 두 작업이 모두 유효 함 .
각 작업은 가중치 가중치 (i, j)로 미리 설정되어 있습니다. 이제 리소스 제약으로 인해 실행할 작업을 k 개만 선택할 수 있습니다. 실행 된 모든 작업이 효율적이고 실행 된 모든 작업의 ​​가중치 합계가 최대화되기를 바랍니다.

입력 첫
번째 줄은 두 개의 정수 n과 k입니다.
다음 n 행, i 번째 행 (1 <= i <= n)에는 i 개의 정수가 포함되어 각 작업의 가중치를 제공합니다. 이 삼각형은 또한 작업의 종속성을 설명합니다.
출력
출력에는 필요한 최대 가중치 합계 인 정수만 포함됩니다.

입력 샘플
3 4
1
2 3
1 1 1
샘플 출력
6

힌트
30 % 데이터의 경우 1 <= n, k <= 50;
100 % 데이터의 경우 1 <= n <= 100, 1 <= m <= C (n + 1, 2), 1 <= weight (i , j) <= 1000.

 

이 주제는 선분 트리와 약간 비슷하고 동적 프로그래밍과 비슷합니다. 어쨌든 쓰기 시작하기 전에 끝냈습니다. 제출할 수 없기 때문에 쓰고 싶지 않습니다.

답은 동적 프로그래밍입니다.

다음은 Toutiao의 공식 계정에 게시 된 답변입니다.

동적 프로그래밍.

 

그림과 같이 Job (i, j)을 선택하면 Job (i + 1, j)을 동시에 선택하는 것 외에도 Job (i + 1, j + 1), Job (i + 2, j + 2)… Job (i + d, j + d)이 모든 체인을 선택해야합니다. 각 슬래시는 접미사를 선택하는 것이므로 동적 계획을 위해 여러 단계로 나눌 수 있습니다.

f [i, j, m]은 처음 i 개의 슬래시를 나타내고 총 m 개의 작업이 선택되었음을 고려합니다.이 중 i 번째 슬래시는 아래에서 위로 j 개의 작업의 최대 가중치 합계를 선택하고 전송 i-1 슬래시> = j-1에 대해 선택할 작업 수를 확인하십시오. 상태 전이 방정식은 다음과 같습니다.

f [i, j, m] = max (f [i-1, j2, m-j]) + sum [i, j] (j-1 <= j2 <= i)

여기서 sum [i, j]는 i 번째 대각선의 하위 j 개 작업 가중치의 합을 나타냅니다. 이 전환의 복잡성은 O (n)이고 총 복잡성은 O (n ^ 3 * m)에 도달하여 요구 사항을 충족하지 않습니다. 문제의 핵심은 max (f [i-1, j2, m-j])를 빠르게 얻는 방법입니다. 여기에는 많은 최적화 방법이 있습니다. 두 가지 방법이 간략하게 언급됩니다.

  1. 각 슬래시의 f 배열 접미사 최대 값을 유지하기 위해 다른 배열을 사용합니다. 그러면 용어 max (f [i-1, j2, m-j])는 O (1)에 의해 얻을 수 있습니다.

  2. f의 정의를 i 번째 대각선이 아래에서 위로 j 태스크의 최대 가중치 합계를 선택하도록 변경합니다. 그러면 전송할 때 j2를 열거 할 필요가 없습니다. 특정 전달 방정식은 다시 유도 할 수 있도록 남겨집니다.

최적화 후 O (n ^ 2 * m)의 시간 복잡도를 얻을 수 있습니다.
물론이 주제는 다른 상태 분할 방법을 가질 수도 있습니다. Job (i, j)이 선택되면 Job (i + 1, j + 1), Job (i + 1, j), Job (i + 2, j)… Job (n, j) 외에 )이 체인도 선택되어야하며, 그러면 전달 방정식도 위와 대칭적인 방식으로 구성 될 수 있습니다. 시간 복잡도도 O (n ^ 2 * m)입니다.

 

2017 년 필기 시험 문제?

위 코드의 소스를 모르겠습니다. 공식 코드 일 수 있습니다.

내 솔루션에 대해 이야기하겠습니다.

먼저 방정식을 단순화하십시오. x + yx | y = 0

이 방정식의 좌변은 x & y로 단순화 할 수 있습니다.

따라서 방정식은 x & y = 0입니다.

이제 문제는 다음과 같이 변환됩니다. x & y = 0을 만족하는 k 번째로 작은 양의 정수를 찾습니다.

내 코드 :

#include<iostream>
using namespace std;
 
int main()
{
	int x, k, y, t;
	while (cin >> x >> k)
	{
		t = 1, y = 0;
		while (k)
		{
			if (x % 2 == 0)y += t*(k % 2), k /= 2;
			x /= 2, t *= 2;
		}
		cout << y << endl;
	}
	return 0;
}

 

추천

출처blog.csdn.net/nameofcsdn/article/details/112210335