A题
大水题,求最大连续数多少个和最小的最大连续数多少个。
最多连续个数,毫无疑问就是perfect的个数全都连续才最多。注意最少的个数是要平均分,比如一共8个其中6个perfect,分成2,2,2连续的个数才是最少的,如果有比2小的就会有比2大的,那么最小的最大的连续数就>2了
#include
using namespace std;
int main()
{
int t;
cin>>t;
while(t--)
{
int n,m;
cin>>n>>m;
cout<=2*m-1)
cout<<'1'<m)
{
double mm=1.0*n/(n-m+1))>n/(n-m+1)?n/(n-m+1)+1:n/(n-m+1);//平分m, 一共(n-m+1)个位置
//类似于分苹果,只能整个分
cout<
也可以这样想
#include
using namespace std;
int main()
{
int t;
cin>>t;
while(t--)
{
int n,m;
cin>>n>>m;
cout<
H题
可以dp,可以区间修改,可以前缀和。
步数为偶数次时与初始状态相同,奇数次时与初始状态相反。
用区间修改和前缀和比较好想,每过一个点修改区间里的步数,区间修改线段树或树状数组维护,红灯步数+2,绿灯步数+1,利用奇偶数步判断状态。
dp: 样例3:11010
dp[3]所包含的所有时间为 t[0,1],t[1,2],t[2,3],t[1,2],t[2,3]和t[2,3] 即 t[0,2]+t[2,3],t[1,2]+t[2,3]和t[2,3]
其中 t[0,2],t[1,2]即dp[2],第三个t[2,3]就是判断第二个灯的状态是s[2]。
设change(i,j) 表示从i处到j处红绿灯变化的总次数, 计算第一个t[2,3]需要知道change[0,2], 如果change[0,2]是偶数,则计算t[2,3]时原先的红绿灯状态不变,反之,改变状态。 计算第二个t[2,3]亦是如此,需要知道change[1,2]。难点就在于change[0,2]与change[1,2]。
计算容易发现change[0,2]=3,change[1,2]=1;
且通过计算其他的change[l,m](i
此时易得后前个t[2,3]的值是一样的, 都和change[1,2]的奇偶以及s[2]状态有关故后两个t[2,3]的和x为
if(change[1,2]为偶)
x=2*(s[2]=='1'?1:2);
else
x=2*(s[2]=='1'?2:1);
因为如果s[1]==1则change[1,2]=1,如果是s[1]=0,则change[1,2]=0,即是s[i]奇change[i,i+1]奇,反之亦然。
由伪代码可以得到,1->2点 s[1]奇s[2]奇,步数=2;s[1]偶s[2]偶,步数=2;s[1]奇s[2]偶,步数=1;s[1]偶[2]奇,步数=1;
所以
(i-1)->i的步数= s[i-1]==s[i]?2:1;
if-else语句合并为
x=2*(s[i-1]==s[i]?2:1);
由此得dp[i]
dp[i]=dp[i-1]+(i-1)*((s[i]==s[i-1])?2:1)+((s[i]=='1')?1:2);
AC代码:
#include
using namespace std;
const int maxn=100000+5;
long long dp[maxn];
int main()
{
int t;
cin>>t;
while(t--)
{
string s;
cin>>s;
s='0'+s; //s[i]下标从0开始,而规律是从1开始,所以在前面补一位
memset(dp,0,sizeof dp);
dp[1]=(s[1]=='1'?1:2); //根据第一个灯状态,得dp[1]
for(int i=2;i
J题
两个人B,D按 按钮,灯不亮,按一下变亮,灯亮着,计数器+1,按按钮的时间点分别是a,c的整数倍,若时间点相同,则B先D后,按下按钮后倒计时器变为v+0.5(不管按钮前是多少)。
这个题可以模拟,可能因为我太弱惹2333,模拟总是超时(;´ ༎ຶ Д ༎ຶ` ),然后就总数减去不ok的数得到ok的数......
#include
using namespace std;
#define LL long long
const int N = 2e6+5;
LL f[N];
int main()
{
int T;
scanf("%d", &T);
while(T--)
{
LL v, t;
int a, b, c, d;
scanf("%d%d%d%d%lld%lld", &a, &b, &c, &d, &v, &t);
int n=0;
for(int i=0;i
K题
两个数的异或小于这两个数,即看二进制最高位是否相同,相同的话肯定小于这两个数
#include
using namespace std;
#define LL long long
const int N = 32;
int ans[N];
int main()
{
int T;
scanf("%d", &T);
while(T--)
{
int n;
scanf("%d", &n);
memset(ans, 0, sizeof(ans));
int x;
while(n--)
{
scanf("%d", &x);
int num = 0;
while(x>0)
{
x>>=1;
++num;
}
++ans[num];
}
/* for(int i=0;i