cf725F Family Photos

本文探讨了一种涉及游戏策略的贪心算法问题,通过分析姐妹间的照片选择游戏,揭示了最优策略背后的数学原理。玩家的目标是最大化自己与对手之间的快乐度差距,而非单纯追求个人的最大利益。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Alice and Bonnie are sisters, but they don't like each other very much. So when some old family photos were found in the attic, they started to argue about who should receive which photos. In the end, they decided that they would take turns picking photos. Alice goes first.

There are n stacks of photos. Each stack contains exactly two photos. In each turn, a player may take only a photo from the top of one of the stacks.

Each photo is described by two non-negative integers a and b, indicating that it is worth a units of happiness to Alice and b units of happiness to Bonnie. Values of a and b might differ for different photos.

It's allowed to pass instead of taking a photo. The game ends when all photos are taken or both players pass consecutively.

The players don't act to maximize their own happiness. Instead, each player acts to maximize the amount by which her happiness exceeds her sister's. Assuming both players play optimal, find the difference between Alice's and Bonnie's happiness. That is, if there's a perfectly-played game such that Alice has x happiness and Bonnie has y happiness at the end, you should print x - y.

Input

The first line of input contains a single integer n (1 ≤ n ≤ 100 000) — the number of two-photo stacks. Then follow n lines, each describing one of the stacks. A stack is described by four space-separated non-negative integers a1, b1, a2 and b2, each not exceeding 109. a1 and b1 describe the top photo in the stack, while a2 and b2 describe the bottom photo in the stack.

Output

Output a single integer: the difference between Alice's and Bonnie's happiness if both play optimally.

Examples
Input
2
12 3 4 7
1 15 9 1
Output
1
Input
2
5 4 8 8
4 12 14 0
Output
4
Input
1
0 10 0 10
Output
-10

 

这题是神贪心。。

考虑一对照片(a,b)--(c,d),其中(a,b)在上

那么对于A,如果他先取得a,那么B会取到d,这样是a-d。否则B先取到b,A再取到c,这样是c-b。如果A要先取,应当是a-d>=c-b的,为了不让B获得更多价值,A才会先取。a-d>=c-b移项得到a+b>=c+d

同样对于B,如果他先取得b,那么A会取到c,这样是b-c。否则A先取到a,B再取到d,这样是d-a。同样的,B要先取应当满足b-c>=d-a。移项变成a+b>=c+d,结果竟然跟A先取的条件一样了

这说明对于a+b>=c+d的照片,A、B都会想要先取以拉开差距。

对于a+b<c+d的,A、B先手取都不利于获得差值,显然都希望对方先取。如果a+d>=b+c的都取完了,大家都不先手取了,那么实际上此时a+b<c+d的先手取还是有一点关系的。

如果a>d,说明A先取还是能拉开一点差距的,虽然不如B先取A再取能拉开更大差距,但是B显然也不可能先取的。

同样的,如果b>c,说明B先取也能拉开一点差距。

这些照片可以在a+b>=c+d的取完之后再考虑取。

最后,如果有a+d<b+c&&a<=d&&b<=c的,显然A和B取了都不优,所以扔掉。

再把一张照片(x,y)做变换成((x+y)/2,(x+y)/2),答案预先加上个(x-y)/2。这样取了A,答案贡献是(x-y)/2+(x+y)/2=x,取了B,答案贡献是(x-y)/2-(x+y)/2=-y。这样每张照片对A和B价值都是一样的,可以排序完A和B轮流去取。要注意除2之后可能有0.5,要用double

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cstring>
 4 #include<cstdlib>
 5 #include<algorithm>
 6 #include<cmath>
 7 #include<queue>
 8 #include<deque>
 9 #include<set>
10 #include<map>
11 #include<ctime>
12 #define LL long long
13 #define inf 0x7ffffff
14 #define pa pair<int,int>
15 #define mkp(a,b) make_pair(a,b)
16 #define pi 3.1415926535897932384626433832795028841971
17 using namespace std;
18 inline LL read()
19 {
20     LL x=0,f=1;char ch=getchar();
21     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
22     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
23     return x*f;
24 }
25 double p[200010];
26 int n,cnt;
27 double ans;
28 inline void solve(int a,int b)
29 {
30     ans+=(double)(a-b)/2;
31     p[++cnt]=(double)(a+b)/2;
32 }
33 int main()
34 {
35     n=read();
36     for (int i=1;i<=n;i++)
37     {
38         LL a=read(),b=read(),c=read(),d=read();
39         if (a+b>=c+d)
40         {
41             solve(a,b);
42             solve(c,d);
43         }else
44         {
45             if (a>=d)solve(a-d,d-a);
46             if (b>=c)solve(c-b,b-c);
47         }
48     }
49     sort(p+1,p+cnt+1,greater<double>());
50     for (int i=1;i<=cnt;i++)
51     {
52         if (i&1)ans+=p[i];
53         else ans-=p[i];
54     }
55     printf("%.0f\n",ans);
56 }
cf 725F

 

转载于:https://www.cnblogs.com/zhber/p/7283672.html

地图上除了聚合点和起点终点,什么都没有显示<!-- hybrid/html/map.html --> <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width,initial-scale=1.0"> <title>高德地图</title> <!-- <script src="https://webapi.amap.com/loader.js"></script> --> <script src="https://cdn.bootcss.com/vue/2.6.11/vue.js"></script> <style> #map-container { width: 100%; height: 584px; border-radius: 22px; z-index: 4; } /* 聚合点样式(参考官方示例的内联样式+CSS结合) */ .cluster-marker { background: #FF9A44 !important; border-radius: 50% !important; width: 40px !important; height: 40px !important; display: flex !important; align-items: center !important; justify-content: center !important; color: white !important; font-weight: bold !important; z-index: 1000 !important; box-shadow: 0 2px 6px rgba(0, 0, 0, 0.5) !important; border: 2px solid white !important; } /* 新增:隐藏高德默认标记图标 */ #map-container .amap-marker img[src*="mark_bs.png"] { display: none !important; } #map-container .amap-marker-content { overflow: visible !important; z-index: 1000 !important; } </style> </head> <body> <div id="map-container"></div> <script type="text/javascript" src="./js/uni.webview.0.1.52.js"> </script> <script> window._AMapSecurityConfig = { securityJsCode: 'cf331d54f67e306ca5c0b17f7122d559' }; </script> <script src="https://webapi.amap.com/maps?v=2.0&key=f3323c24769b10828db07f07c0fcec0d&plugin=AMap.MarkerCluster"> </script> <script src="https://webapi.amap.com/ui/1.1/main.js"></script> <script> // 确保UniApp通信桥接准备就绪 function setupUniBridge() { console.log('window--uni', uni); return new Promise(resolve => { if (typeof uni.postMessage === 'function') { console.log('window--uni', window.uni); return resolve(); } document.addEventListener('UniAppJSBridgeReady', resolve); }); } // 向UniApp发送消息 async function sendMessageToUniApp(data) { await setupUniBridge(); if (window.uni && typeof uni.postMessage === 'function') { console.log('window--uni--00', window.uni); uni.postMessage({ data: JSON.stringify(data) // 发送字符串 }); } else if (window.parent) { console.log('window--uni--11', window.uni); window.parent.postMessage({ type: 'webviewMessage', data: JSON.stringify(data) }, '*'); } } // 解析URL参数 const params = new URLSearchParams(location.search); const points = JSON.parse(params.get('points') || '[]'); const markers = JSON.parse(params.get('markers') || '[]'); // 初始化地图 const map = new AMap.Map('map-container', { zoom: 10, center: [points[0].lng, points[0].lat], showBuildingBlock: true }); // 自定义单个标记内容(保持原有样式,修复图片路径) function createMarkerContent(markerData) { // 优先使用本地图片,失败则用备用图(确保是自定义图标) const imageUrl = './img/flag.png'; const fallbackUrl = 'https://picsum.photos/40/50'; // 替换为你的自定义备用图 // 生成唯一的类名,避免样式冲突 const uniqueClass = `marker-${Date.now()}-${Math.random().toString(36).substr(2, 5)}`; return ` <div class="${uniqueClass}" style="position:relative; z-index:1000;"> <!-- 强制隐藏可能存在的默认图标和加载失败的图片 --> <style> /* 隐藏高德默认图标 */ #map-container .amap-marker img[src*="mark_bs.png"] { display: none !important; } /* 只显示成功加载的图片(本地图或备用图) */ .${uniqueClass} img { display: block !important; width:40px !important; height:50px !important; } </style> <img src="${imageUrl}" alt="${markerData.title}" onerror="this.src='${fallbackUrl}'; console.error('图片加载失败,使用备用图')"> <div style="position:absolute; bottom:-20px; left:50%; transform: translateX(-50%); background: rgba(227, 57, 59, 0.1); padding:3px 8px; border-radius: 18px; white-space:nowrap; font-family:ShuHuiTi, sans-serif; font-size: 12px; font-weight: bold; border: 2px solid #F47C58; color:#E4393C;"> ${markerData.title} </div> </div> `; } // 聚合点渲染函数(参考官方示例的context处理) function _renderClusterMarker(context) { const count = context.count; console.log('渲染聚合点,数量:', count); // 参考官方示例:通过JS直接设置样式(优先级更高) const div = document.createElement('div'); div.className = 'cluster-marker'; div.innerHTML = count; // 强制设置关键样式(覆盖默认) div.style.width = '40px'; div.style.height = '40px'; div.style.backgroundColor = '#FF9A44'; div.style.borderRadius = '50%'; // 官方示例:设置聚合点偏移(确保居中) context.marker.setOffset(new AMap.Pixel(-20, -20)); context.marker.setContent(div); // 关键:通过context.marker设置内容 } // 单个标记渲染函数(参考官方示例的_renderMarker命名和参数) function _renderMarker(context) { const markerData = context.data[0].originalData; console.log('渲染单个标记:', markerData); const marker = new AMap.Marker({ position: [markerData.lng, markerData.lat], content: createMarkerContent(markerData), offset: new AMap.Pixel(-20, -50), // 精确偏移 anchor: 'bottom-center', zIndex: 1000 }); // 绑定点击事件 marker.on('click', async () => { await sendMessageToUniApp({ type: 'markerClick', data: markerData }); }); return marker; } // 绘制路线(保持原有功能) function drawRouteAndPoints() { if (points.length === 0) return; const path = points.map(p => [p.lng, p.lat]); new AMap.Polyline({ path: path, strokeColor: "#32CD32", strokeWeight: 5, zIndex: 500, map: map }); if (points.length >= 2) { AMap.plugin('AMap.Driving', () => { const driving = new AMap.Driving({ map: map, policy: AMap.DrivingPolicy.LEAST_TIME, zIndex: 550 }); driving.search( [points[0].lng, points[0].lat], [points[points.length - 1].lng, points[points.length - 1].lat] ); }); } } // 初始化聚合标记(核心:按官方示例配置参数) function initClusterMarkers() { if (!markers.length) return; // 转换数据格式为官方示例要求的结构(包含lnglat字段) const clusterPoints = markers.map(marker => ({ lnglat: new AMap.LngLat(marker.lng, marker.lat), // 官方要求的经纬度格式 originalData: marker // 保留原始数据供渲染使用 })); // 参考官方示例:插件加载后初始化聚合 AMap.plugin('AMap.MarkerCluster', function() { if (typeof AMap.MarkerCluster === 'undefined') { console.error('聚合插件加载失败'); return; } // 核心:按官方示例配置聚合参数 const cluster = new AMap.MarkerCluster(map, clusterPoints, { gridSize: 80, // 网格大小(官方示例默认60,可调整) maxZoom: 18, // 最大聚合级别 minClusterSize: 2, // 最小聚合数量(测试时可改为1) zoomOnClick: true, averageCenter: true, zIndex: 1000, // 官方示例:聚合点渲染函数参数名 renderClusterMarker: _renderClusterMarker, // 官方示例:单个标记渲染函数参数名 renderMarker: _renderMarker }); // 调整视野(保持原有功能) const bounds = new AMap.Bounds(); clusterPoints.forEach(point => bounds.extend(point.lnglat)); map.setBounds(bounds, [50, 50, 50, 50]); if (clusterPoints.length === 1) { map.setZoom(15); } }); } // 地图加载完成后初始化(保持原有功能) map.on('complete', function() { console.log('地图加载完成,初始化组件'); initClusterMarkers(); if (points.length > 0) drawRouteAndPoints(); }); map.on('error', (err) => console.error('地图错误:', err)); // 构建带标题的HTML内容 // markers.forEach(marker => { // // 构建HTML内容(包含图片和标题) // const content = ` // <div style="background: linear-gradient(180deg, #E3383B 0%, #F47C58 98%); padding:6px; border-radius: 8px;"> // <div style=" white-space:wrap; // font-family:AlibabaPuHuiTi-SemiBold; font-size: 15px; // margin-top:5px;color:#fff;width:100%;">闽宁新貌展示中心</div> // <div style=" white-space:wrap;text-indent: 1em;letter-spacing: 1px; // font-family:AlibabaPuHuiTi-RegularL3; font-size: 10px; // margin-top:5px;color:#fff;width:100%;"> // 闽宁新貌展示中心,生动呈现闽宁协作丰硕成果,见证昔日“干沙滩”蜕变为今日“金沙滩”的壮丽历程。 </div> // <img src="./img/ditu.png" style="width:200px; height:110px; display:block;margin-top:5px;"> // </div> // `; // const markerObj = new AMap.Marker({ // position: [marker.lng, marker.lat], // content: content, // 使用HTML内容 // anchor: 'bottom-center', // 锚点在底部中心 // offset: new AMap.Pixel(0, -25) // 向上偏移 // }); // markerObj.on('click', () => { // console.log('window--uni', uni, window); // // console.log(marker, '000'); // // 将数据转为字符串 // const message = JSON.stringify({ // type: 'markerClick', // title: marker.title // }); // window.parent.postMessage(message, '*'); // // 通过uni.postMessage发送数据 // // uni.postMessage({ // // data: JSON.stringify(message) // 发送字符串 // // }); // }); // map.add(markerObj); // }); // 2. 在map加载完成后初始化聚合点 // map.on('complete', function() { // // 创建聚合实例 // const cluster = new AMap.MarkerClusterer(map, markers.map(m => { // return new AMap.Marker({ // position: [m.lng, m.lat], // content: createMarkerContent(m) // 自定义标记 // }); // }), { // gridSize: 80, // maxZoom: 18, // renderClusterMarker: renderCluster // }); // // // 转换数据格式 // // const clusterPoints = markers.map(marker => ({ // // lnglat: [marker.lng, marker.lat], // // title: marker.title, // // originalData: marker // 保留原始数据 // // })); // // console.log('在map加载完成后初始化聚合点', clusterPoints); // // // 确保有聚合点数据 // // if (clusterPoints.length === 0) return; // // 使用MarkerCluster插件 // // AMap.plugin('AMap.MarkerCluster', function() { // // console.log("聚合插件加载完成"); // // // 创建聚合点 // // const cluster = new AMap.MarkerCluster(map, clusterPoints, { // // gridSize: 80, // 聚合网格像素大小 // // maxZoom: 18, // 最大聚合级别 // // minClusterSize: 2, // 最小聚合数量 // // zoomOnClick: true, // 点击聚合点是否放大地图 // // averageCenter: true, // 聚合点是否使用平均值中心 // // // 定义聚合点样式 // // renderClusterMarker: function(context) { // // console.log('定义聚合点样式-context', context); // // // const count = context.count; // // // const div = document.createElement('div'); // // // div.innerHTML = ` // // // <div style="background: #FF9A44; // // // border-radius: 50%; // // // width: 40px; // // // height: 40px; // // // display: flex; // // // align-items: center; // // // justify-content: center; // // // color: white; // // // font-weight: bold; // // // z-index:99;"> // // // ${count} // // // </div> // // // `; // // const count = context.count; // // const div = document.createElement('div'); // // div.style.background = '#FF9A44'; // // div.style.borderRadius = '50%'; // // div.style.width = '40px'; // // div.style.height = '40px'; // // div.style.display = 'flex'; // // div.style.alignItems = 'center'; // // div.style.justifyContent = 'center'; // // div.style.color = 'white'; // // div.style.fontWeight = 'bold'; // // div.style.zIndex = '99'; // // div.innerHTML = count; // // // context.marker.setContent(div); // // return div; // // }, // // // 自定义标记点样式 // // renderMarker: function(context) { // // const markerData = context.data[0].originalData; // // // console.log('自定义标记点样式-context', context); // // // const marker = new AMap.Marker({ // // // position: [markerData.lng, markerData.lat], // // // content: ` // // // <div style="position:relative; text-align:center;z-index:100;"> // // // <img src="./img/flag.png" // // // style="width:40px; height:50px; display:block;"> // // // <div style="position:absolute; bottom:-90%; left:0%; transform:translateX(-50%); // // // background: rgba(227, 57, 59, 0.1); padding:6px 0; // // // border-radius: 18px; white-space:wrap; // // // font-family:ShuHuiTi; font-size: 12px;font-weight: bold; // // // margin-top:5px;border: 2px solid #F47C58;color:#E4393C;width:80px;"> // // // ${markerData.title} // // // </div> // // // </div> // // // `, // // // offset: new AMap.Pixel(0, 0) // // // }); // // // 创建自定义内容 // // const content = ` // // <div style="position:relative; text-align:center;z-index:100;"> // // <img src="./img/flag.png" style="width:40px; height:50px; display:block;"> // // <div style="position:absolute; bottom:-90%; left:50%; transform:translateX(-50%); // // background: rgba(227, 57, 59, 0.1); padding:6px 0; font-family:ShuHuiTi; font-size: 12px;font-weight: bold; // // margin-top:5px;border: 2px solid #F47C58;color:#E4393C;width:80px; border-radius: 18px;"> // // ${markerData.title} </div> </div> `; // // const marker = new AMap.Marker({ // // position: [markerData.lng, markerData.lat], // // content: content, // // offset: new AMap.Pixel(-2, -4) // 根据实际图片调整偏移 // // }); // // // 绑定聚合点点击事件 // // // marker.on('click', async function(e) { // // // console.log(e, 'bbbbb'); // // // sendMessageToUniApp({ // // // type: 'markerClick', // // // center: e.lnglat // // // }); // // // }); // // // // console.log('聚合点点', marker); // // // map.add(marker); // // // 绑定标记点击事件 // // marker.on('click', async function(e) { // // 发送消息给UniApp // // await sendMessageToUniApp({ // // type: 'markerClick', // // data: markerData // // }); // // }); // // return marker; // // }, // // }); // // // 绑定聚合点点击事件 // // cluster.on('click', async function(e) { // // console.log(e, 'bbbbb'); // // // 发送聚合点点击事件 // // await sendMessageToUniApp({ // // type: 'clusterClick', // // data: { // // count: e.clusterData.count, // // center: e.clusterData.center, // // markers: e.clusterData.markers // // } // // }); // // }); // // }); // }); // 2. 绘制路线 // const path = points.map(p => [p.lng, p.lat]); // new AMap.Polyline({ // path: path, // strokeColor: "#32CD32", // strokeWeight: 5, // map: map // }); // 3. 添加起点终点标记 // points.forEach((point, i) => { // new AMap.Marker({ // position: [point.lng, point.lat], // // content: `<div class="point-label">${i === 0 ? '起' : '终'}</div>`, // offset: new AMap.Pixel(-10, -10), // map: map // }); // }); // 4. 绘制驾车路径(如果需要,可以注释掉直线路径,保留驾车路径) // 注意:这里同时绘制了直线和驾车路径,可能会重叠 // if (points.length >= 2) { // AMap.plugin('AMap.Driving', () => { // const driving = new AMap.Driving({ // map: map, // 这样驾车路线会直接显示在地图上 // policy: AMap.DrivingPolicy.LEAST_TIME // }); // driving.search( // [points[0].lng, points[0].lat], // [points[points.length - 1].lng, points[points.length - 1].lat], // (status, result) => { // // 可以根据结果处理 // } // ); // }); // } // 1. 绘制路线 // if (points.length > 0) { // const path = points.map(p => [p.lng, p.lat]); // new AMap.Polyline({ // path: path, // strokeColor: "#32CD32", // strokeWeight: 5, // map: map // }); // // 添加起点终点标记 // points.forEach((point, i) => { // new AMap.Marker({ // position: [point.lng, point.lat], // offset: new AMap.Pixel(-10, -10), // map: map // }); // }); // // 绘制驾车路径(如果需要) // if (points.length >= 2) { // AMap.plugin('AMap.Driving', () => { // const driving = new AMap.Driving({ // map: map, // policy: AMap.DrivingPolicy.LEAST_TIME // }); // driving.search( // [points[0].lng, points[0].lat], // [points[points.length - 1].lng, points[points.length - 1].lat] // ); // }); // } // } </script> </body> </html>
08-09
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值