给你stick(棍)和diamonds的个数。
要你转换成shovel(铁铲)或swords。
(shovel 需要 2* stick 1* diamond 。 sword 需要 1* stick 2* diamond )
要你把他们卖掉,卖掉shovel和swords都可以得到1 * emerald(绿宝石)
题目给你stick和diamond数,问你最多有多少个绿宝石。
其实就是2,1分配的问题。
每次操作都是2,1分配到 两个容器里(容器即stick和diamond,而题目给的stick数和diamond数,就是容器的上限)。
把问题转换成:最多操作几次,直到容器装不下了。
最多进行(s+d)/3 (因为每次操作都要2,1即三个空间,不管它往哪边放,反正最好是全放完)。
可是上面贪心是不严谨的
假如s,d为10, 1 按照上述贪心,ans应该是3,但是ans是1.
所以最后的答案ans,还要和s,d之中最小那个比较。
x=min(s,d),y=max(s,d)。
cout<
做的时候,贪心不严谨,1wa,其实这道题,我的贪心漏洞很容易发现。
以后打cf记住一句化就行了**“稳中求胜”**
#include
#define For(i,x,y) for(register int i=(x); i<=(y); i++)
using namespace std;
int main()
{
ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
int t;
cin>>t;
while(t--)
{
int a,b;
cin>>a>>b;
int minx=min(a,b);
if(a==0||b==0)cout<<0<<endl;
else cout<<min((a+b)/3,minx)<<endl;
}
return 0;
}
给你一个初始为1的位置,问你经过m次操作后,最多有几个位置是1(每次操作可以自己和自己换)
区间更新,先找到包含x的区间(l,r),之后遇到和(l,r)相交的区间就更新 l=min(l,a),r=max(r,b)
这里可能取区间交时,条件有点多,可以取下对立情况。(详见ac1和ac2)
对于特判没想好,其实题目已经明确了,特判是原封不动即1,(我却傻傻的输出0,哎,直接如土了)
#include
#define For(i,x,y) for(register int i=(x); i<=(y); i++)
using namespace std;
int main()
{
ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
int t;
cin>>t;
while(t--)
{
int a,b,n,flag=0,l=0,r=1e9+10,m,x;
cin>>n>>x>>m;
For(i,1,m)
{
cin>>a>>b;
if(!flag&&a<=x&&x<=b)
{
flag=1;
l=a;r=b;
}
else if(flag&&( (b<=r&&b>=l) || (a>=l&&a<=r)||(a<=l&&b>=r) ))
{
l=min(l,a);
r=max(r,b);
}
}
if(r==1e9+10)cout<<1<<endl;//我原本输出0,3wa
else cout<<r-l+1<<endl;
}
return 0;
}
#include
#define For(i,x,y) for(register int i=(x); i<=(y); i++)
using namespace std;
int main()
{
ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
int t;
cin>>t;
while(t--)
{
int n,m,x,a,b;
cin>>n>>x>>m;
int l=x,r=x;
For(i,1,m)
{
cin>>a>>b;
if(b<l||a>r)continue;//取相反的条件,直接太麻烦了
l=min(a,l);
r=max(b,r);
}
cout<<r-l+1<<endl;
}
return 0;
}
本题其实问改变最少,使得所有路径都是对称的,就是画对角线。
#include
#define For(i,x,y) for(register int i=(x); i<=(y); i++)
using namespace std;
int a[40][40],ans=0;
int n,m,sj;
void check(int x, int y)
{
int cnt0=0,cnt1=0,i=x,j=y;
while(i>0&&i<=n&&j>0&&j<=m)
{
if(a[i][j]==1)cnt1++;
else cnt0++;
if(a[n-i+1][m-j+1]==1)cnt1++;//对称的那条对角线
else cnt0++;
i++,j--;
}
ans+=min(cnt1,cnt0);
}
int main()
{
ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
int t;
cin>>t;
while(t--)
{
cin>>n>>m;
sj=(n+m+1)/2;
ans=0;
For(i,1,n)For(j,1,m)cin>>a[i][j];
int x=1,y=1;
For(i,1,sj-1)
{
check(x,y);//cout<
if(i<m)y++;//注意对角线的画法
else x++;
}
cout<<ans<<endl;
}
return 0;
}