#include<iostream>
#include<cstdio>
using namespace std;
int main()
{
int n,L,a;
int t,l;
int cnt=0;
int ans=0;
scanf("%d%d%d",&n,&L,&a);
if(n==0)
{
cout<<L/a<<endl;
return 0;
}
while(n--)
{
scanf("%d%d",&t,&l);
cnt=cnt+(t-ans)/a;
ans=t+l;
}
cnt=cnt+(L-ans)/a;
cout<<cnt<<endl;
return 0;
}
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
char mp[1006][1006];
int vis[1006][1006];
int dir[8][2]={-1,-1,-1,0,-1,1,0,-1,0,1,1,-1,1,0,1,1};
int n,m;
int check(int x,int y)
{ int fx,fy;
for(int i=0;i<8;i++)
{
fx=x+dir[i][0];
fy=y+dir[i][1];
if(mp[fx][fy]=='.')
return 0;
}
return 1;
}
void change(int x,int y)
{
int fx,fy;
for(int i=0;i<8;i++)
{
fx=x+dir[i][0];
fy=y+dir[i][1];
vis[fx][fy]=1;
}
}
int judge()
{
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
if(mp[i][j]=='#'&&!vis[i][j])
return 0;
}
}
return 1;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=0;i<n;i++)
scanf("%s",mp[i]);
memset(vis,0,sizeof(vis));
for(int i=1;i<n-1;i++)
{
for(int j=1;j<m-1;j++)
{
if(check(i,j))
change(i,j);
}
}
if(judge())
cout<<"YES"<<endl;
else
cout<<"NO"<<endl;
return 0;
}
1.题意:
最初给一个1、2、3、……、n的序列,每次操作先将所有元素的最大公约数加入答案序列,然后在序列中任意删除一个数,一直重复至序列为空,求字典序最大的答案序列。
2.思路:
2.1 当n<4时,需要特殊处理。当n>=4时,要使结果序列的字典序最大,那么必须尽快得到大于1的最大公约数,容易想到,2这个最大公约数是最快可以得到的,因为所有偶数都有2这个约数,先删除所有奇数,所得到的所有结果元素为1,这时候原序列所有元素的最大公约数为2。
2.2接着,因为总是想让字典序最大,那么就要尽快得到大于2的最大公约数,此时含公约数4的元素占序列中元素数量的一半。(2,4,6,8,10,12,14,16……),将公约数2提出,序列再次变为(1,2,3,4,5,6,7,8……),此时在偶数位上的元素都是含公约数4的元素,删除奇数位上的元素,结果序列加入结果元素2,删除完后,序列中所有元素均含后公约数4。依次类推,直至原序列元素个数<4。
2.3总的来说,第一次循环: 就是有几个奇数就输出几个1,然后剩下的偶数中进行第二次循环,分一半输出2,另外一半进行第三次循环,一次类推,知道n==3结束。
3. 代码:
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n,ans=1;
scanf("%d",&n);
while(n)
{
if(n==3)
{
printf("%d %d %d\n",ans,ans,ans*3);
break;
}
else
{
for(int i=0;i<(n+1)/2;i++)
printf("%d ",ans);
//cout<<"n="<<n<<",ans="<<ans<<endl;
}
n=n/2;
ans=ans*2;
cout<,
}
return 0;
}