COJ 1156 Switching bulbs

一道模拟题目

对于所有0 还是 1 我们都可以想象做均为 0 的状态

v[i]表示原来的值

但是对于原来为1的要加上其所在的值作为初始值

然后转化后 a[i] = -v[i]  , 如果原来为0 , 那就直接赋值

 

我们总是希望将尽可能大的值先加 ,所以将a由大到小排个序 ,  一直加到负数的时候需要考虑这个负数取不取,其实我们最多取一个负数,因为当加了

第一个负数若后面还为负数,那么我们可以将那个负数倒转又加回来即可

但第一个负数取不取也要看它的绝对值是不是比前一个数大,如果大,说明宁可将前一个数再变一次颜色后舍去也不需要加后一个负数

 

最后我们就确定实际上使用的数了,如果操作数大于这个数,说明超过范围只是不断的将最小的数不断改变颜色

 1 #include <cstdio>

 2 #include <algorithm>

 3 using namespace std;

 4 

 5 const int N = 100005;

 6 int col[N] , v[N] , a[N];

 7 

 8 bool cmp(int a , int b)

 9 {

10     return a>b;

11 }

12 

13 int main()

14 {

15    // freopen("a.in" , "r" , stdin);

16     int n , m;

17     while(scanf("%d%d" , &n , &m) == 2)

18     {

19         for(int i = 0 ; i<n ; i++)

20             scanf("%d" , col+i);

21         for(int i = 0 ; i<n ; i++)

22             scanf("%d" , v+i);

23 

24         int val = 0;

25         for(int i=0 ; i<n ; i++)

26             if(col[i]){

27                 val += v[i];

28                 a[i] = -v[i];

29             }

30             else{

31                 a[i] = v[i];

32             }

33         sort(a , a+n , cmp);

34         for(int i = 0 ; i<n ; i++){

35             if(a[i] < 0){

36                 if(i == 0){

37                     n = 1;

38                     break;

39                 }

40                 if(-a[i] > a[i-1]) n = i;

41                 else n = i+1;

42                 break;

43             }

44         }

45         if(m<=n){

46             for(int i = 0 ; i<m ; i++)

47                 val += a[i];

48         }

49         else{

50             for(int i = 0 ; i<n ; i++){

51                 val += a[i];

52             }

53             if((m-n)&1) val -= a[n-1];

54         }

55         printf("%d\n" , val);

56     }

57     return 0;

58 }

 

你可能感兴趣的:(switch)