目录
A - Full Moon
B - Overlapping sheets
C - Blue Spring
D - General Weighted Max Matching
E - Sandwiches
F - Octopus
#include
using namespace std;
const int N=1e6+5;
typedef long long ll ;
const int maxv=4e6+5;
typedef pair pll;
void solve()
{
int n,m,p;
cin>>n>>m>>p;
if(m>n) cout<<0<>t;
while(t--){
solve();
}
system("pause");
return 0;
}
一眼扫描线,感觉人都魔楞了
#include
using namespace std;
const int N=1e6+5;
typedef long long ll ;
const int maxv=4e6+5;
typedef pair pll;
int st[105][105];
void solve()
{
int n;
cin>>n;
for(int i=1;i<=n;i++){
int a,b,c,d;
cin>>a>>b>>c>>d;
for(int l=a+1;l<=b;l++){
for(int r=c+1;r<=d;r++){
st[l][r]=1;
}
}
}
int cnt=0;
for(int i=0;i<105;i++){
for(int j=0;j<105;j++){
if(st[i][j]) cnt++;
}
}
cout<>t;
while(t--){
solve();
}
system("pause");
return 0;
}
思路:贪心,考虑购票乘车票的代价和直接购票的代价即可。
#include
using namespace std;
const int N=1e6+5;
typedef long long ll ;
const int maxv=4e6+5;
typedef pair pll;
int st[105][105];
void solve()
{
int n,d,p;
cin>>n>>d>>p;
vector a(n+5),s(n+5);
for(int i=1;i<=n;i++) cin>>a[i];
sort(a.begin()+1,a.begin()+1+n,greater());
for(int i=1;i<=n;i++){
s[i]=s[i-1]+a[i];
}
ll ans=1e18;
for(int i=1;i<=n;i++){
ll t=(i+d-1)/d;
ll v=t*p;
if(v>t;
while(t--){
solve();
}
system("pause");
return 0;
}
思路:搜索,思路和全排列搜索比较类似。
#include
using namespace std;
const int N=1e6+5;
typedef long long ll ;
const int maxv=4e6+5;
typedef pair pll;
int n;
ll g[20][20];
int st[20];
ll res;
ll ans;
void dfs(int x)
{
if(x>n){
ans=max(ans,res);
return ;
}
if(st[x]){
dfs(x+1);
return ;
}
for(int i=x+1;i<=n;i++){
if(!st[i]&&!st[x]){
st[i]=st[x]=1;
res+=g[x][i];
dfs(x+1);
res-=g[x][i];
st[i]=st[x]=0;
}
}
dfs(x+1);
}
void solve()
{
//int n;
cin>>n;
for(int i=1;i<=n-1;i++){
for(int j=i+1;j<=n;j++){
int w;
cin>>w;
//cout<>t;
while(t--){
solve();
}
system("pause");
return 0;
}
思路:因为要求和相同,考虑,使用桶去记录每个相同数字的下标,然后对每个数字进行枚举中间量,对于中间量的枚举,如果我们对每个桶中的每个下标进行枚举,肯定会超时,考虑优化:我们发现,对于一个桶,我们计算到当前量j,那么其对答案的贡献为,s表示的个数,所以我们可以对这个前缀和再求一遍前缀和即可。
具体注释看代码。
#include
using namespace std;
const int N=1e6+5;
typedef long long ll ;
const int maxv=4e6+5;
typedef pair pll;
typedef array p3;
const int mod=1e9+7;
vector mp[N];
void solve()
{
int n;
cin>>n;
ll res=0;
vector a(n+5);
for(int i=1;i<=n;i++){
cin>>a[i];
mp[a[i]].push_back(i);
}
for(int i=1;i<=n;i++){
auto v=mp[i];
vector b(v.size()+5),s(v.size()+5);
for(int j=1;j ss(v.size()+5);
for(int j=1;j>t;
while(t--){
solve();
}
system("pause");
return 0;
}
思路:对于一个位置k,我们考虑其是否合法,贪心的去想,我们将坐标和k的绝对值按升序排序,若每一个能和排序后的一一对应(即其都在的那个区间内)。但因为k所能选的点的范围为1e18,我们不能去一一枚举,那么我们就考虑去寻找区间。
在寻找区间前,我们考虑当位于k时合法,位于k+1时不合法的情况,那么我们会发现仅有符合条件。
同样,我们考虑位于k时不合法,位于k+1合法的情况,仅有。符合条件。
所以我们一共会得到2*n*n个点,我们去检查每个点是否合法即可。
#include
using namespace std;
const int N=1e6+5;
typedef long long ll ;
const int maxv=4e6+5;
typedef pair pll;
typedef array p3;
const int mod=1e9+7;
int n;
vector x(205),l(205);
bool check(ll k)
{
sort(x.begin()+1,x.begin()+1+n,[&](ll x,ll y){
return abs(k-x)l[i]) return false;
}
return true;
}
void solve()
{
// int n;
cin>>n;
for(int i=1;i<=n;i++){
cin>>x[i];
}
for(int i=1;i<=n;i++) cin>>l[i];
vector s;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
s.push_back(x[i]+l[j]);
s.push_back(x[i]-l[j]-1);
}
}
sort(s.begin(),s.end());
sort(l.begin()+1,l.begin()+1+n);
ll ans=0;
for(int i=1;i>t;
while(t--){
solve();
}
system("pause");
return 0;
}