A:模拟即可
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int M =1e5+7;
int main()
{
ios::sync_with_stdio(false);cin.tie(0);
int h,w,k;
cin>>w>>h>>k;
int ans=0;
for(int i=1;i<=k;i++)
{
ans+=((h-(i-1)*4-1)*2+(w-(i-1)*4-1)*2);
}
cout<<ans<<endl;
return 0;
}
B:
知道 a|b 和a&b 后 ab的值就确定了。
这是个不错的性质,以后应该能用上,VP时候临时推的。
证明:我们二进制每一位来看。某一位 a&b=1那么 a,b都是1 a&b=0 a|b=0 a,b都是0 ;a&b=0,a|b=1 a,b有一个是1一个是0
所以我们只需要枚举第一个t,然后后面的t都是确定的
模拟下即可。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int M =1e5+7;
int a[M],b[M],c[M];
bool f;
int n;
int main()
{
ios::sync_with_stdio(false);cin.tie(0);
cin>>n;
for(int i=2;i<=n;i++)cin>>a[i];
for(int i=2;i<=n;i++)cin>>b[i];
for(int j=0;j<=3;j++)
{
for(int i=1;i<=n;i++)c[i]=-1;
c[1]=j;
bool f=true;
for(int i=2;i<=n;i++)
{
for(int k=0;k<=3;k++)
if(((k&c[i-1])==b[i])&&((k|c[i-1])==a[i]))
c[i]=k;
if(c[i]==-1)f=false;
}
// for(int i=1;i<=n;i++)
// cout<<c[i]<<" ";
// cout<<endl;
if(f)
{
cout<<"YES"<<endl;
for(int i=1;i<=n;i++)
cout<<c[i]<<" ";
cout<<endl;
return 0;
}
}
cout<<"NO"<<endl;
return 0;
}
C:二分读到第几个笔记。
有两天在学习,其中一天一定可以填满,(从大到小贪心的填)这样另外一天剩的笔记天数是固定的,能就是能,不能就是不能。
满足二分性,二分搞搞即可
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int M =1e5+7;
int p[M],q[M],vs[M];
int sa,sb;
bool ck(int x,int a,int b)//看到第几个笔记
{
sa=sb=0;
memset(vs,0,sizeof(vs));
for(int i=x;i>=1;i--)
if(a>=i)a-=i,vs[i]=1;
ll nw=0;
for(int i=1;i<=x;i++)
if(!vs[i])nw+=i;
if(nw<=b)return true;
return false;
}
int main()
{
ios::sync_with_stdio(false);cin.tie(0);
int a,b;
cin>>a>>b;
int l=1,r=1e5+7,ans=0;
while(l<=r)
{
int mid=(l+r)/2;
//cout<<l<<" "<<r<<" "<<mid<<endl;
if(ck(mid,a,b))l=mid+1,ans=mid;
else r=mid-1;
}
//cout<<ans<<endl;
sa=sb=0;
memset(vs,0,sizeof(vs));
for(int i=ans;i>=1;i--)
if(a>=i)a-=i,p[++sa]=i,vs[i]=1;
for(int i=1;i<=ans;i++)
if(!vs[i])q[++sb]=i;
sort(p+1,p+1+sa);
cout<<sa<<endl;for(int i=1;i<=sa;i++)cout<<p[i]<<" ";
cout<<endl;
cout<<sb<<endl;for(int i=1;i<=sb;i++)cout<<q[i]<<" ";
cout<<endl;
return 0;
}
D:
明显的贪心:前面经过的点不是'a' 必然把他换成'a '更优。
所以我们枚举步数,在这一步中选择最优的一个或多个解,然后走下一步。(可以预处理下到i,j.'a'的数量最多的路径是多少)
具体看代码,感觉这种处理比较简单。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int M =2000+7;
char s[M][M];
int f[M][M];//到 x,y的所有路径中, 'a'的个数最多的路径是多少
int vs[M][M];
int main()
{
int n,k;
cin>>n>>k;
for(int i=1;i<=n;i++)scanf("%s",s[i]+1);
for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)f[i][j]=-1e9;
f[1][1]=(s[1][1]=='a');
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
if(f[i][j]+k>=i+j-1)s[i][j]='a';
f[i+1][j]=max(f[i][j]+(s[i+1][j]=='a'),f[i+1][j]);
f[i][j+1]=max(f[i][j]+(s[i][j+1]=='a'),f[i][j+1]);
}
vs[1][1]=1;
for(int step=1;step<=2*n-1;step++)
{
char ch='z';
for(int i=1;i<=n;i++)
{
int j=step-i+1;
if(j<1||j>n||!vs[i][j])continue;
ch=min(ch,s[i][j]);
}
for(int i=1;i<=n;i++)
{
int j=step-i+1;
if(j<1||j>n)continue;
if(s[i][j]==ch&&vs[i][j])vs[i+1][j]=vs[i][j+1]=1;
}
cout<<ch;
}
cout<<endl;
return 0;
}