腾讯笔试题 安排机器

/*
*下面的代码只AC了40%,我认为是对我的算法思路对测试数据造成了遗漏
*我的思路是先按照时间和等级进行贪心排序,因为时间的影响力比等级大,所以把时间作
*为第一排序选择;然后循环选择机器时间大于任务时间,且机器等级大于任务等级的任务
*数组下标,在计算moreIncome和count同时,将机器和任务的数据置为-1,以下面的测
*试数据为例,最后count比正确答案的值小1存在着遗漏,漏掉了13 99这组任务数据,
*具体怎么遗漏的呢?我认为是这样的:这种算法策略是同时找到符合机器时间大于任务时间,
*机器等级大于任务等级的条件就break,然后计算,但数据量变大后,且越计算到后面,
*由于只要一找到符合条件的数据就break,这会发生你现在break的机器数据不能更好的体现它的价值,
*怎么个不好法,不够贪心吧,其实你的这组机器数据用到后面更能体现价值。当然这只是我的猜想,
*没用数据来证实,如果哪位大佬看见了,希望能解答下这个疑惑。
*/
#include <bits/stdc++.h>
using namespace std;
const int maxn = 100005;
struct node {
	int x, y;
}machine[maxn], task[maxn], test[maxn];

int cmp(node a, node b)
{
	if (a.x == b.x) 
		return a.y > b.y;
	return a.x > b.x;
}

int main()
{
	int n = 0, m = 0, count = 0, k=0;
	long long moreIncome = 0;
	scanf ("%d %d", &n, &m);
	for (int i=0; i<n; i++)
	{
		scanf ("%d %d", &machine[i].x, &machine[i].y);
	}
	for (int i=0; i<m; i++)
	{
		scanf ("%d %d", &task[i].x, &task[i].y);
	}
	sort (machine, machine+n, cmp);
	sort (task, task+m, cmp);
	
	printf ("***************************\n");
//	printf ("machine:\n");
//	for (int i=0; i<n; i++)
//		printf ("%d %d\n", machine[i].x, machine[i].y);
//	printf ("+++++++++++++++++++++++++++\n");
//	printf ("task:\n");
//	for (int i=0; i<m; i++)
//		printf ("%d %d\n", task[i].x, task[i].y);
//	printf ("***************************\n");
		
	for (int i=0; i<n; i++)
	{
		int flag1 = -1, flag2 = -1;
		for (int j=0; j<m; j++)
		{
			if ( machine[i].x>=task[j].x && machine[i].x>0 && task[j].x>0 
			&& machine[i].y>=task[j].y && machine[i].y>0 && task[j].y>0)
			{
				flag1 = i;
				flag2 = j;
				break;
			}
		}
		if (flag1 != -1 && flag2 != -1) {
//			printf ("machine[flag1].x, machine[flag1].y, task[flag2].x, task[flag2].y = %d %d %d %d\n", 
//				machine[flag1].x, machine[flag1].y, task[flag2].x, task[flag2].y);
//			printf("task[flag2].x task[flag2].y = %d %d\n", task[flag2].x, task[flag2].y); 
			test[k].x = task[flag2].x;
			test[k].y = task[flag2].y;
			k++;
			moreIncome += 200 * task[flag2].x + 3 * task[flag2].y;
			task[flag2].x = -1;
			machine[flag1].x = -1;
			task[flag2].y = -1;
			machine[flag1].y = -1;
			count++;
		}
	}
	sort(test, test+k, cmp);
	for (int i=0; i<k; i++)
	{
		printf ("test[i].x  test[i].y = %d %d\n", test[i].x, test[i].y);
	}
	printf("**************************\n");
	printf ("%d %lld", count, moreIncome);
	return 0;
}


/*
*这段代码AC的样例全通过
*思想:先对机器和任务进行从大到小的贪心排序,具体和上面一样,然后贪心的找符合条
*件的任务。怎么贪心呢?以任务出发循环,先找出时间大于任务的机器,然后将机器的等
*级放入cnt[]中,接着以任务的等级为起点,循环找到最近是否有大于此等级的机器,使用
*下面的测试数据,对过程进行打印,你会发现最后的machine[j-1].time machine[j-1].priority
*有重复的数据,这是因为任务和机器都是以时间进行排序,那么先被cnt[]数组记录等级的
*机器,只要出现小于他等级的任务,一定可以完成,但我没有很好地打印,所以出现这种情况
*/
#include <bits/stdc++.h>
using namespace std;
const int maxn = 100005;
struct node {
    int time, priority;
}machine[maxn], task[maxn];
int cnt[105];
int cmp(node a ,node b){
    if(a.time == b.time)return a.priority > b.priority;
    return a.time > b.time;
}
int main(){
    int n,m;
    scanf("%d%d",&n,&m);
    for(int i = 0;i < n;i++) scanf("%d%d",&machine[i].time, &machine[i].priority);
    for(int i = 0;i < m;i++) scanf("%d%d",&task[i].time, &task[i].priority);
    sort(machine, machine + n,cmp);
    sort(task, task + m,cmp);
    int num = 0;
    long long ans = 0;
    memset(cnt,0,sizeof(cnt));
    int i,j,k;
    printf ("******************************\n");
    for(i = 0,j = 0;i < m;i++){
        while(j < n && machine[j].time >= task[i].time){
//        	printf ("进入while\n");
//        	printf ("machine[j].time task[i].time = %d %d\n", machine[j].time, task[i].time);
            cnt[machine[j].priority]++;
            j++;
        }
//        printf ("退出while\n");
//        printf ("machine[j-1].time machine[j-1].priority = %d %d\n", machine[j-1].time, machine[j-1].priority);
        for(k = task[i].priority;k <= 100;k++){
            if(cnt[k]){
//            	printf("开始比较等级\n"); 
                num++;
                cnt[k]--;
                ans = ans + 200 * task[i].time +3 * task[i].priority;
                printf ("task[i].time task[i].priority = %d %d\n",
						 task[i].time, task[i].priority);
                break;
            }
        }
    }
    printf ("****************************\n");
    printf("%d %lld\n",num,ans);
    return 0;
}


/*测试数据取自牛客网
77 51
599 10
420 55
533 70
969 70
925 12
765 18
942 51
483 62
691 74
798 43
912 58
807 83
543 80
756 69
762 95
62 68
122 8
902 66
971 28
308 88
625 76
411 74
974 90
229 66
320 98
956 69
862 23
613 37
783 21
690 85
858 5
698 99
748 50
231 79
916 91
221 2
609 57
40 99
282 27
281 8
436 16
736 100
667 71
314 68
889 26
883 43
531 81
989 38
724 23
12 46
652 91
978 47
730 67
241 74
878 19
619 60
796 73
885 96
861 61
187 57
888 69
815 19
863 97
816 26
295 93
281 95
917 59
820 99
311 15
89 62
784 97
6 51
653 61
715 98
77 60
965 70
748 94
518 69
963 60
19 91
125 36
844 97
447 10
523 100
778 65
219 25
255 95
889 21
27 11
905 14
740 58
755 89
531 92
941 58
712 10
894 71
837 11
705 77
577 89
388 27
64 84
382 5
115 91
919 46
885 30
16 91
490 79
297 28
870 49
407 65
205 91
796 61
624 39
966 91
264 35
167 65
177 19
56 16
144 95
974 80
49 79
13 99
86 46
93 79
354 93
573 12
487 9
666 49
*/

来一张打印图,没截取,左边是第一段代码,右边是第二段代码

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值