TC SRM515 div2

  在做这场比赛,我也是在赛后做的。

  level 1:我们只要枚举出所以可能的组合,在判断是不是一个fortunate number就可以了。

  level 2:我们可以枚举mark的位置,这样我们就能算出时针和分针的位置,我们根据计算出来的角度,判断这样的角度是不是合法的。如果是合法的,我们就可以根据角度来计算出时间了。

  level 3:这题我想了一下午,一直没有想出来,后来看了别人的一个程序,后面才慢慢地弄懂。后来才发现,自己下午想了一下午,并没有想出一个比较合适的分组。我们可以这样考虑,当我们选择了一个时间点,假设一个用户会在这个时间点来买东西,那么我们就假设在这之前,他们都没有来店里。所以这样就能找到一个划分,我们再根据这个划分来算出每一个划分的结果,再相加就可以了。

#define max(a , b) (a > b ? a : b)

struct Node
{
	int t;
	int c;
	double p;
}a[60] , b[60];
int lena , lenb;

int cmp(const void *a , const void *b)
{
	Node *c = (Node *)a;
	Node *d = (Node *)b;
	return c->t - d->t;
}

class NewItemShopTwo
{
        public:
        double getMaximum(vector <string> customers)
        {
			double ret;
			double pa , pb;
			int indexa , indexb;

			process(a , customers[0] , lena);
			process(b , customers[1] , lenb);

			qsort(a , lena , sizeof(a[0]) , cmp);
			qsort(b , lenb , sizeof(b[0]) , cmp);

			indexa = 0;
			indexb = 0;
			pa = 1;
			pb = 1;

			ret = 0;
			for (int i=0 ; i<24 ; i++) {
				if (a[indexa].t == i) {
					ret += a[indexa].p * pb * max(a[indexa].c , getExpect(b , indexb , lenb));
					pa = pa - a[indexa].p;
					indexa++;
					if (b[indexb].t == i) {
						pb = pb - b[indexb].p;
						indexb++;
					}
				}
				else if (b[indexb].t == i) {
					ret += b[indexb].p * pa * max(b[indexb].c , getExpect(a , indexa , lena));
					pb = pb - b [indexb].p;
					indexb++;
				}
			}
			
			return ret;
		}

		double getExpect(Node a[] , int index , int len)
		{
			double p = 1;
			double ret = 0;

			for (int i=0 ; i<index ; i++) {
				p -= a[i].p;
			}

			for (int i=index ; i<len ; i++) {
				ret += (a[i].c * a[i].p / p);
			}

			return ret;
		}
		
		void process(Node a[] , string customer , int &len) 
		{
			int st;
			len = 0;

			st = 0;
			for (int i=0 ; i<customer.length() ; i++) {
				if (customer[i] == ' ') {
					a[len++] = getNode(customer , st , i - 1);
					st = i + 1;
				}
			}
			a[len++] = getNode(customer , st , customer.length() - 1);
		}
		
		Node getNode(string customer , int st , int en)
		{
			Node ret;
			
			int pos = st;
			for (int i=st ; i<=en ; i++) {
				if (customer[i] == ',') {
					ret.t = transformStringtoInt(customer , pos , i - 1);
					pos = i + 1;
					st = i + 1;
					break;
				}		
			}

			for (int i=st ; i<=en ; i++) {
				if (customer[i] == ',') {
					ret.c = transformStringtoInt(customer , pos , i - 1);
					pos = i + 1;
					st = i + 1;
					break;
				}
			}

			ret.p = transformStringtoInt(customer , pos , en) / 100.0;
			
			return ret;
		}
		
		int transformStringtoInt(string str , int st , int en)
		{
			int ret = 0;
			for (int i=st ; i<=en ; i++) {
				ret *= 10;
				ret += (str[i] - '0');
			}	

			return ret;
		}

};
ps:level 3我是根据别人的源程序,在加上自己的理解做的。在编写代码的时候难免受到之前看的代码的影响,所以虽然通过了System Test,这只能代表我的程序是对的。如果我的理解有问题,望指出。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值