A. A Prank
题目链接:http://codeforces.com/contest/1062/problem/A
题目大意:n个数,输入n个数,然后对于这些数,看最多能够擦除多少个数,还能还原出原数组。
这些数范围:1~1000。
方法:下标相减==里面的元素值相减则是能够删掉的,然后特判一下头和尾(取其中能够删除最多的元素)
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<stdlib.h>
//#include<map>
//#include<set>
#include<deque>
#include<queue>
#include<stack>
#include<bitset>
#include<string>
#include<fstream>
#include<iostream>
#include<algorithm>
using namespace std;
#define ll long long
//#define max(a,b) (a)>(b)?(a):(b)
//#define min(a,b) (a)<(b)?(a):(b)
#define clean(a,b) memset(a,b,sizeof(a))// ˮӡ
//std::ios::sync_with_stdio(false);
const int MAXN=1e5+5;
const ll INF=1e18;
const ll mod=1e9+7;
int arr[MAXN];
int main()
{
std::ios::sync_with_stdio(false);
int n;
while(cin>>n)
{
for(int i=1;i<=n;++i)
cin>>arr[i];
int ans=0,res=0;
int res1=0,res2=0;//头和尾的可删除元素个数
for(int i=1,j=1;i<=n;++i)
{
if((arr[i]-arr[j])==i-j)//删除一个区间
{
if(i-j>1)
res++;
}
else//到该点结束
{
if(arr[j]==1&&i-j>1&&j==1)//特判1~i区间
res1=res+1;
ans=max(ans,res);//取最大的区间
j=i;//刷新
res=0;
}
}
if(arr[n]==1000&&arr[n-1]==999)//特判末尾区间
res2=res+1;
if(arr[1]==1&&arr[n]==n)//特判从头到尾1~n
res1=n-1;
ans=max(ans,res);
ans=max(ans,res1);
ans=max(ans,res2);
cout<<ans<<endl;
}
}
B. Math
题目链接:http://codeforces.com/contest/1062/problem/B
题目大意:给出一个n,然后有两种操作,1.乘上一个数 2.对这个数开平方。求只用这两个操作得出的最小值,并且输出操作次数。
思路:把这些数的素因子提取出来,因为只能开根,因此如果素因子的次幂都是1的话就是最小值了,答案就是所有的素因子的乘积,
至于此树,所以我们可以首先将它乘上一个数,使得所有的素因子的次幂都是2的倍数,然后开2的倍数的平方即可
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<stdlib.h>
//#include<map>
//#include<set>
#include<deque>
#include<queue>
#include<stack>
#include<bitset>
#include<string>
#include<fstream>
#include<iostream>
#include<algorithm>
using namespace std;
#define ll long long
//#define max(a,b) (a)>(b)?(a):(b)
//#define min(a,b) (a)<(b)?(a):(b)
#define clean(a,b) memset(a,b,sizeof(a))// ˮӡ
//std::ios::sync_with_stdio(false);
const int MAXN=1e6+5;
const ll INF=1e18;
const ll mod=1e9+7;
int vis[MAXN];
int main()
{
std::ios::sync_with_stdio(false);
int n;
while(cin>>n)
{
clean(vis,0);
int ans=1;
for(int i=2;i<=n;++i)//求素因子
{
if(n%i==0)
ans=ans*i;
while(n%i==0)//求出素因子的次幂
{
vis[i]++;
n=n/i;
}
}
if(n>1)
vis[n]++;
int maxnum=0;
for(int i=1;i<MAXN;++i)//找出最大的那个次幂
maxnum=max(maxnum,vis[i]);
int i=1,oper=0;
while(i<maxnum)//判断开平方多少次
{
i=i<<1;
oper++;
}
maxnum=i; //乘上去
int f=0;//是否不用乘
for(int j=1;j<MAXN;++j)
{
if(maxnum!=vis[j]&&vis[j])//要乘以一个数
{
f=1;
break;
}
}
if(f)//要乘+1
cout<<ans<<" "<<oper+1<<endl;
else//不用乘
cout<<ans<<" "<<oper<<endl;
}
}
C. Banh-mi
题目链接:http://codeforces.com/contest/1062/problem/C
题目大意:给出n个长度的01串和q次询问,对于每次询问,输入一个区间 l,r,然后找能够按要求的出的最大值,
要求:对于l~r区间的数,取出一个数,然后其他数都加上取出的这个数的值,问最多能取出数的sum最大是多少。
思路:因为是01串,我们每次取最大的就能保证加的最大,稍微模拟一下就可以推出来
MAXsum=2^1的个数的-1+2^1的个数*2^0的个数
特判一下从头开始的:
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<stdlib.h>
//#include<map>
//#include<set>
#include<deque>
#include<queue>
#include<stack>
#include<bitset>
#include<string>
#include<fstream>
#include<iostream>
#include<algorithm>
using namespace std;
#define ll long long
//#define max(a,b) (a)>(b)?(a):(b)
//#define min(a,b) (a)<(b)?(a):(b)
#define clean(a,b) memset(a,b,sizeof(a))// ˮӡ
//std::ios::sync_with_stdio(false);
const int MAXN=1e5+5;
const ll INF=1e18;
const ll mod=1e9+7;
int arr[MAXN];
ll res[MAXN];
int main()
{
std::ios::sync_with_stdio(false);
int n,q;
string s;
res[0]=1;
for(int i=1;i<MAXN;++i)
res[i]=(res[i-1]*2)%mod;//2的i次幂预处理出来
while(cin>>n>>q)
{
cin>>s;
int len=s.size();
arr[0]=(s[0]=='1')?1:0;
for(int i=1;i<len;++i)
arr[i]=arr[i-1]+s[i]-'0';//获得1的个数
int l,r;
while(q--)
{
cin>>l>>r;
l--,r--;
if(l) //区间
{
ll x=res[arr[r]-arr[l-1]]-1;//
ll y=res[r-l+1-(arr[r]-arr[l-1])];
cout<<(x*y)%mod<<endl;
}
else//从第一个开始
{
ll x=res[arr[r]]-1;//
ll y=res[r-l+1-(arr[r])];
cout<<(x*y)%mod<<endl;
}
}
}
}
D. Fun with Integers
题目链接:http://codeforces.com/contest/1062/problem/D
好水的一道题啊!就是题目不好看懂,看懂之后就超简单!!
题目大意:给一个数n,然后找里面所有满足(2≤|a|,|b|≤n)的一对a和b,然后再找出x满足1<|x| 和 (a⋅x=b||b⋅x=a)
然后看样例,发现复数和正数是分开算的,于是对于每一对a,b都有四个答案,遍历一遍加起来即可:
int main()
{
std::ios::sync_with_stdio(false);
int n;
while(cin>>n)
{
ll ans=0;
for(int i=2;i<=n;++i)
{
for(int j=2;j*i<=n;++j)
ans+=j*4;
}
cout<<ans<<endl;
}
}