CF-926
两点睡,七点起,阎王夸我好身体......
主要这场实在是难绷,两个小时都在C题上吊死了,也不是没想过跳题,只是后面的题我更是一点思路都没有-^-
"就喜欢这种被揭穿的感觉,爽!"
B
分析
涂色的单元格能够包含k种对角线,很明显要根据图像的具体性质想答案:
然而我赛时是一股脑地猜结论,这种方法在赛时不确定性还是太大了,希望自己能尽快把思维这方面的短板补起来......
上色时考虑单种特殊点对其它特殊点及答案的贡献。
- 四个顶点:作图发现只有同侧的两个顶点对答案的贡献是2,另外两个是1;再分析发现,顶点包含的是一条最短和一条最长的对角线,前者只经过它自己,后者还要经过(n-1)个格子,所以上色一个顶点后会使(n-1)个处于最长对角线上的格子贡献-1
- 中心点或者说不在边缘位置的点:对他们上色就会使经过它们包含的两种对角线的格子贡献-1------其中包括处于顶点,非边缘位置的点,边缘位置的格子
- 边缘位置的点:对他们上色就会使处于非边缘位置的格子贡献-1
要使答案最小,我们涂色的格子的贡献一定尽量都是2 ,若贡献为2的格子涂完了再考虑贡献为1的格子,再结合上面三种点位的性质,我们发现涂顶点与边缘位置的格子 才会使可选格子贡献值最大(涂色不在边缘位置的格子影响的格子数更多,涂它们比不涂它们会使贡献为2的格子更少)。由此再考虑使涂色这两种格子对其它格子影响最小,先涂的格子一定都在同一侧,有n个,而其余贡献为2的格子是对侧的边缘位置的格子,有(n-2)个,剩下的可选格子贡献都为1。
比如图示3*3的红色部分
操作
因此,有w=(n*2-2)个格子贡献为2,(w乘2)>=k时,答案为(k/2)向上取整,否则,还要涂k-(w乘2)个贡献为1的格子,答案为k-(w乘2)+w=k-w。
为了规避markdown语法......
代码
c++
#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
#define int long long
#define db(x) cout<<x<<" "<<endl;
#define _db(a,n) for(int i=1;i<=n;i++) cout<<a[i]<<" ";cout<<endl;
#define mem(a) memset(a,0, sizeof(a))
//int qz(int k){
// if(k%2==0) return k/2;
// else return k/2+1;
//}
signed main()
{
std::ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int t,n,k,w,ans=0;cin>>t;
while(t--){
cin>>n>>k;
w=n*2-2;
//身为蒟蒻现在才学会怎么向上取整很合理吧......
if(w*2>=k) ans=(k+1)/2;//ans=qz(k);
else ans=k-w;
cout<<ans<<endl;
}
return 0;
}
C
更新中(/头秃)