比赛新机制
题意:一个环,任取一个起点和一个方向(正方向 Or 逆方向),求总罚时最短
思路:罚时是解每道题目的时间的和,显然要用前缀和来解答,求一次前缀和,即求出每个题的罚时
复盘:两个方向,想到了要用两个前缀和来维护
最初的想法,想对前缀和再求取一次前缀和(见代码(43~51),想通过新的前缀和直接得到从每个点出发的总罚时————这样是错的(写题要有条理)
最后饶了半天,才发现要从第一次前缀和入手,然后就推出来了两个计算公式
坑点:要用快读,数据 (10^5) * (10^5) …
Ac Code:
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N=1000005;
int a[N], s1[N], s2[N];
int minn(int a,int b)
{
if(a<b) return a;
return b;
}
inline int read()
{
int X=0; bool flag=1; char ch=getchar();
while(ch<'0'||ch>'9') {if(ch=='-') flag=0; ch=getchar();}
while(ch>='0'&&ch<='9') {X=(X<<1)+(X<<3)+ch-'0'; ch=getchar();}
if(flag) return X;
return ~(X-1);
}
signed main()
{
int t,n;
scanf("%lld",&t);
while(t--)
{
//memset(s1,0,sizeof s1);
//memset(s2,0,sizeof s2);
n = read();
int sum1=0, sum2=0;
for(int i=1;i<=n;i++)
{
a[i] = read();
//a[i+n] = a[i];
s1[i] = s1[i-1]+a[i];
sum1 += s1[i];
}
s2[n+1]=0;
for(int i=n;i>=1;i--)
{
s2[i] = s2[i+1]+a[i];
sum2 += s2[i];
}
/*
for(int i=1;i<=n;i++)
{
s1[i] += s1[i-1];
}
for(int i=n;i>=1;i--)
{
s2[i] += s2[i+1];
}*/
int ans = 1e17;
for(int i=1;i<=n;i++)
{
int cnt=n-i+1;
ans=min(ans,sum1-cnt*s1[i-1]+(n-cnt)*(s1[n]-s1[i-1]));
ans=min(ans,sum2-i*s2[i+1]+(n-i)*(s2[1]-s2[i+1]));
}
printf("%lld\n",ans);
/*cout<<sum1<<' '<<sum2<<' '<<ans<<endl;
for(int i=1;i<=n;i++) cout<<s1[i]<<' ';cout<<endl;
for(int i=1;i<=n;i++) cout<<s2[i]<<' ';cout<<endl;
*/
}
return 0;
}
生命的游戏
暴力~
Ac Code:
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N=1005;
int minn(int a,int b)
{
if(a<b) return a;
return b;
}
int a[N][N], b[N][N], t[N][N];
int dx[10]={0,0,1,1,1,-1,-1,-1};
int dy[10]={1,-1,0,1,-1,0,1,-1};
void change(int n)
{
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
t[i][j] = b[i][j];
int cnt=0;
for(int p=0;p<8;p++)
{
int x=(i+dx[p]+n-1)%n+1, y=(j+dy[p]+n-1)%n+1;
if(b[x][y]) cnt++;
}
if(b[i][j] && (cnt>3 || cnt<2)) t[i][j]=0;
if(!b[i][j] && cnt==3) t[i][j]=1;
}
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++) b[i][j]=t[i][j];
}
}
signed main()
{
int t,n, k;
scanf("%lld",&t);
while(t--)
{
//memset(s1,0,sizeof s1);
//memset(s2,0,sizeof s2);
scanf("%lld%lld",&n,&k);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
scanf("%lld",&a[i][j]);
b[i][j]=a[i][j];
}
}
int flag=1;
for(int p=1;p<=k;p++)
{
int fg=1;
change(n);
for(int i=1;i<=n && fg;i++)
{
for(int j=1;j<=n && fg;j++)
{
if(b[i][j]!=a[i][j]) fg = 0;
}
}
if(fg)
{
cout<<"YES"<<endl<<p<<endl;
flag=0;
break ;
}
}
if(flag) cout<<"NO"<<endl;
}
return 0;
}
飞马分隔符
注意子串"FeiMa"是非连续的!!
Ac Code:(solution one)
#include <bits/stdc++.h>
using namespace std;
string str = "FeiMa";
int main()
{
int n, t;
cin>>t;
while(t--)
{
cin>>n;
string s;
cin>>s;
int fg=1, ans=0, p=0;
while(fg)
{
for(int i=0; i<5 && fg; i++)
{
p = s.find(str[i], p);
if(p==-1) fg = 0;
}
if(fg) ans++;
}
cout<<ans<<endl;
}
return 0;
}
Ac Code:(solution two)
#include <bits/stdc++.h>
using namespace std;
string str = "FeiMa";
int main()
{
int n, t;
cin>>t;
while(t--)
{
cin>>n;
string s;
cin>>s;
int fg=0, ans=0;
for(int i=0; i<n; i++)
{
if(fg==0 && s[i]==str[0]) fg++;
if(fg==1 && s[i]==str[2]) fg++;
if(fg==2 && s[i]==str[3]) fg++;
if(fg==3 && s[i]==str[4]){ fg = 0; ans++; }
}
cout<<ans<<endl;
}
return 0;
}