地址
A烧烤温度
贪心思路比较容易想到的。
错:
写成z1=max(0,(k-b)/y+1); 以为k<b时能正确处理
实际上会abs(k-b)<y时,z1=1,会出错。
z2也一样
点击查看代码
#include<bits/stdc++.h>
using namespace std;void solve(){int k,a,b,x,y;cin>>k>>a>>b>>x>>y;int ans,z1=0,z2=0;if(x>y){if(k>=b){z1=(k-b)/y+1;k-=z1*y;}if(k>=a){z2=(k-a)/x+1;}ans=z1+z2;}else{if(k>=a){z1=(k-a)/x+1;k-=z1*x;}if(k>=b){z2=(k-b)/y+1;}ans=z1+z2;}cout<<ans<<endl;return ;
}signed main(){int t;cin>>t;while(t--) solve();return 0;
}
B屋顶板覆盖屋顶
贪心思路也是比较容易想的
外围是可以延伸出去的,借助外围向外铺屋顶板,矛盾就在内部
错:
以为只有当最初的两块屋顶板x方向有重叠或y方向有重叠时才需要判断dif是否被a或b边整除
实际上画图得出不论重叠与否,difx和dify至少有一个能够整除a或b才是Yes,否则为No(在x方向和y方向不重叠的前提下)
1.特判if(x1=x2)和if(y1=y2) 这种情况下一个dif为0一定可以满足,但是需保证另一个dif必须满足,即两个dif满足
2.else的情况(x有交集或y有交集或都没有交集)两个dif至少有一个满足就能借助外围的特性塞满。
trick:
求dif时可以直接用两个左下顶点x和y分别相减求得
求得的dif正好是一个a或b加上需要的dif(在相离的情况下)
或者不足一个a或b(在相交的情况下)
取模时不会受到影响
点击查看代码
#include<bits/stdc++.h>
using namespace std;void solve(){int w,h,a,b,x1,y1,x2,y2;cin>>w>>h>>a>>b>>x1>>y1>>x2>>y2;if(x1==x2){int dif=abs(y1-y2)%b;if(dif) cout<<"No"<<endl;else cout<<"Yes"<<endl;return ;}if(y1==y2){int dif=abs(x1-x2)%a;if(dif) cout<<"No"<<endl;else cout<<"Yes"<<endl;return ;}if(abs(x1-x2)%a&&abs(y1-y2)%b) cout<<"No"<<endl;else cout<<"Yes"<<endl;return ;
}signed main(){int t;cin>>t;while(t--) solve();return 0;
}
C金苹果二维前缀和
贪心:
发现选择一个区域用炸弹炸掉后
每次一格一格地移动,可以获得其余所有的金锭
ans=sum-毁掉的金锭
遍历所有的格子,
如果是空地,计算产生爆炸毁掉的金锭数,存最小的毁掉的金锭数
快速计算爆炸范围内毁掉的金锭数:二维前缀和\(O(1)\)实现
二维前缀和实现细节和一维其实差不多
前面也是用0来更新,后面注意二维数组越界的问题
trick:
当二维前缀和数组面对越界风险时,
可以max(i-k,0)min(i+k-1,n)
来替换为边界值和0,可以画图很快证明,
对于边界值,超出的部分为空的,超一维还是超两维对应的值都是m和n分别替换后的值
对于0,只要超出0界了,就一定是空的,而0对应的也是空的,所以超一维还是超两维也都是用0替换相应的值
点击查看代码
#include<bits/stdc++.h>
using namespace std;void solve(){int n,m,k;cin>>n>>m>>k;vector<vector<char>> a(n+1,vector<char>(m+1));vector<vector<int>> s(n+1,vector<int>(m+1));for(int i=1;i<=n;i++)for(int j=1;j<=m;j++) cin>>a[i][j];for(int i=1;i<=n;i++)for(int j=1;j<=m;j++) s[i][j]=s[i-1][j]+s[i][j-1]-s[i-1][j-1]+(a[i][j]=='g');int sum=s[n][m];int ans=s[n][m];for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)if(a[i][j]=='.'){int res=s[min(i+k-1,n)][min(j+k-1,m)]-s[max(i-k,0)][min(j+k-1,m)]-s[min(i+k-1,n)][max(j-k,0)]+s[max(i-k,0)][max(j-k,0)];ans=min(ans,res);}cout<<sum-ans<<endl;return ;
}signed main(){int t;cin>>t;while(t--) solve();return 0;
}