第一次水题解,尽管还有三不会
链接
做的时候没想到dp,直接模拟
转化后的字符串可化为 000111000三段,每一段的长度都可能为0
dp数组记录第i个处于第1/2/3段需要删除的最小字符(第个字符可能要被删除)正解是dp
if(s[i]=='1') {
dp[i][0]=dp[i-1][0]+1;
dp[i][1]=min(dp[i-1][0],dp[i-1][1]);
dp[i][2]=min(dp[i-1][1],dp[i-1][2])+1;
}
else {
dp[i][0]=dp[i-1][0];
dp[i][1]=min(dp[i-1][0],dp[i-1][1])+1;
dp[i][2]=min(dp[i-1][1],dp[i-1][2]);
看大佬代码还发现一种神奇的解法
先记录总共的1的数量,然后
int x=0;
for(int i=0;i<n;i++){
if(num[i] == 0) x--;
else x++;
if(x<0) x =0;
maxx = max(x,maxx);
}
cout<<sum-maxx;
比如有一串01010011001
1有5个,更新maxx为2,这里是最大连续的1
又比如有01011111011111111000
这边遇0的x–意义就成了把中间的0去掉
一开始以为是博弈论,后来发现枚举到十就可以找到规律
1 pig
2 cow
3 pig
4 pig
5 cow
6 pig
7 cow
8 pig
9 pig
10 cow
typedef long long ll;
int main()
{
int t;
cin>>t;
while(t--){
int n;
cin>>n;
n%=5;
int flag=0;
if(n==0||n==2)flag=1;
if(flag==1)printf("Cow\n");
else printf("Pig\n");
}
return 0;
}
求q进制下的后导零,而且q是质数,所以有后导零只有可能是阶乘中有q,有几个q就有几个后导零。
这个题的加强版是q不是质数,这个时候就要去打q的因数了
链接
ll N, B;
ll calc(ll n, ll p)
{
ll res = 0;
while(n){
res += n/p;
n/=p;
}
return res;
}
int main()
{
int T;
cin>>T;
while(T--){
ll sum = 1ll;
scanf("%lld %lld", &N, &B);
//get_p(B);
//ll ans = (1ll<<62);
ll ans = calc(N, B);
printf("%lld\n", ans);
}
return 0;
}
看代码,发现规律是(n/k)*(m/k)就好了
int main()
{
int T;
cin>>T;
while(T--){
ll n,m,k;
scanf("%lld%lld%lld",&n,&m,&k);
printf("%lld\n",(n/k)*(m/k));
}
return 0;
}
看我的注释
const int N=1e5+5;
ll n,m,s=1,ans=0,a[N];
int main()
{
cin>>n>>m;
for(int i=1;i<=m;i++) cin>>a[i];
sort(a+1,a+1+m);//先用桶装爱好,装完了排序
for(int i=1;i<=n;i++){
//按座位遍历就好了
if(a[s]<=i){
ans+=i-a[s];
s++;
}
if(s==m+1) break;
}
if(s!=m+1) cout<<-1<<endl;
else cout<<ans<<endl;
return 0;
}
我一看,啪的一下很快啊,这不就是vector吗,stl大法好
#include
#include
using namespace std;
int n,q;
vector <int > v;
int main()
{
cin>>n>>q;
for(int i=0;i<n;i++){
int tmp;
scanf("%d",&tmp);
v.push_back(tmp);
}
while(q--){
int op;
scanf("%d",&op);
if(op==1){
int pos;
scanf("%d",&pos);
v.erase(v.begin()+pos-1);
n--;
for(int i=0;i<n;i++){
cout<<v[i]<<' ';
}
cout<<endl;
}
else if(op==2){
int pos,num;
scanf("%d%d",&pos,&num);
v.insert(v.begin()+pos-1,num);n++;
for(int i=0;i<n;i++){
cout<<v[i]<<' ';
}
cout<<endl;
}
else{
int pos;
scanf("%d",&pos); int tx=v[pos-1];
for(int i=pos;i<n;i++){
if(v[i]==tx){
v.erase(v.begin()+i);
v[pos-1]+=tx;
n--;i--;
}
else{
break;
}
}
for(int i=0;i<n;i++){
cout<<v[i]<<' ';
}
cout<<endl;
}
}
return 0;
}
就正常把圆柱侧面展开,求一下距离就行了,注意夹角可能超过180.
int main() {
int T;
cin>>T;
while(T--){
double a,b,c,d;
cin>>a>>b>>c>>d;
double x;
if(fabs(a-b)>180){
x=360-fabs(a-b);
}
else x=fabs(a-b);
x=x*PI/180;
double t=x*c;
//cout<
double res=t*t+d*d;
printf("%.2f\n",res);
}
return 0;
}