T1 Curriculum Vitae
题意:
输入一串数只有0和1;0不出现在1右,问最少删几个数.
解法:
暴力+技巧.
求在哪个1后只有1.
代码:
#include<bits/stdc++.h>
using namespace std;
int x[100000];
int y[100000];
int z[100000];
int main()
{
int a,b=0,c,d=0;
cin>>a;
c=a+1;
for(int i=1;i<=a;i++)
{
cin>>x[i];
if(x[i]==1)
{
b++;
y[b]=i;
if(i<c)
c=i;
}
}
d=a-(c+b-1);
for(int i=1;i<=b;i++)
{
z[i]=d+i-1;
d-=(y[i+1]-y[i]-1);
}
z[b+1]=b;
sort(z+1,z+b+2);
cout<<a-z[1];
return 0;
}
小结:
**此类题目水题。**
T2 Math Show
题意:
有n个任务,每个都有k个子任务,完成第kj个子任务的时间为 ti,完成一个子任务得一分,而且完成了一个大任务则多得一分.
解法:
枚举加暴力:枚举完成了几个大任务,然后其他的都是子任务,子任务按时间从小到大完成就行
代码:
#include<bits/stdc++.h>
using namespace std;
#define maxn 50
#define LL long long
LL n,k,M;
int a[maxn+5],b[maxn*maxn];
int main()
{
cin>>n>>k>>M;
for(int i=1; i<=k; i++)
cin>>a[i];
LL ans=0,e=0,b=0,c=0,d=0;
sort(a+1,a+k+1);
for(int i=1; i<=k; i++)
e+=a[i];
for(int i=0; i<=n; i++)
{
b = e*i;
if(b>M)
break;
d = b ;
c = (k+1)*i;
for(int j=1; j<=k; j++)
{
for(int r=i+1; r<=n; r++)
{
d+=a[j];
c++;
if(d>M)
{
c--, j = k+1;
break;
}
}
}
ans = max(ans,c);
}
cout<<ans;
return 0;
}
小结:
**此类题目需要特判。**
T3 Four Segments
题意:
给你一个序列,定义一种运算sum(a,b)=num[a]+…+num[b-1],注意sum(a,a)=0。让你求出最大的res=sum(0, delim0) - sum(delim0, delim1) + sum(delim1, delim2) - sum(delim2, n) 时的delim0,delim1,delim2。
解法:
找规律.
代码:
#include<bits/stdc++.h>
#define inf 0x7f7f7f7f
#define LL long long
using namespace std;
LL ans=-inf,n,i,j,k,t[5007],d1,d2,d3,c1,c2,c3,x,ans1,ans2,ans3;
int main() {
for(scanf("%lld",&n),i=1; i<=n; i++) {
scanf("%lld",&x);
t[i]=x+t[i-1];
}
for(c2=0; c2<=n; c2++) {
d2=c2;
d1=d3=d2;
for(c1=0; c1<=c2; c1++)
if(t[c1]>=t[d1]) d1=c1;
for(c3=c2; c3<=n; c3++)
if(t[c3]>=t[d3]) d3=c3;
if(t[d1]+t[d3]-t[d2]>=ans) {
ans=t[d1]+t[d3]-t[d2];
ans1=d1;
ans2=d2;
ans3=d3;
}
}
cout<<ans1<<" "<<ans2<<" "<<ans3;
return 0;
}
小结:
**此类题目需要特判。**
T4 Monitor
题意:
有一块n*m的显示器,在一定时间会有一定的像素坏掉,当有一块K*K的地方坏了,显示器就坏了,输出最短时间.
解法:
暴力.
代码:
#include<bits/stdc++.h>
using namespace std;
#define x first
#define y second
#define pb push_back
typedef long long ll;
typedef pair<int, int> pii;
const int MAXN = 600;
ll n, m, k, q;
ll t[MAXN][MAXN];
ll d[MAXN][MAXN];
bool f(int a){
for(int i=0; i<MAXN; i++)
for(int j=0; j<MAXN; j++)
d[i][j] = 0;
for(int i=1; i<=n; i++){
for(int j=1; j<=m; j++){
if(t[i][j] <= a){
d[i][j] = 1 + min(min(d[i-1][j], d[i][j-1]), d[i-1][j-1]);
if(d[i][j] == k)
return true;
}
}
}
return false;
}
int main(){
for(int i=0; i<MAXN; i++)
for(int j=0; j<MAXN; j++)
t[i][j] = 1e9 + 10;
cin>>n>>m>>k>>q;
while(q--){
ll x, y, z; cin>>x>>y>>z;
t[x][y] =z;
}
ll ans = -1;
ll l=0, r=1e9;
while(l<=r){
ll w = (l+r)/2;
if(f(w)){
ans = w;
r = w-1;
} else
l = w+1;
}
cout<<ans;
return 0;
}
小结:
**此类题目利用预处理,也可以反推。**
T5 Chemistry in Berland
题意:
有n种药,但量可能不够,给出几种转化方法,问药可否补全.
解法:
模拟.
代码:
#include<bits/stdc++.h>
using namespace std;
#define N 100000
#define LL long long
pair<LL,LL> gai[N+5];
LL a,b,c;
double yao[N+5];
int main()
{
cin>>a;
for(int i=1; i<=a; i++)
cin>>yao[i];
for(int i=1; i<=a; i++)
{
cin>>b;
yao[i]=b-yao[i];
}
for(int i=2; i<=a; i++)
{
cin>>gai[i].first>>gai[i].second;
}
for(int i=a; i>1; i--)
{
yao[gai[i].first]+=yao[i]>0?1LL*yao[i]*gai[i].second:yao[i];
}
yao[1]>0?cout<<"NO":cout<<"YES";
}
小结:
**此类题目较难。**
T6 Random Query
题意:
输入一串数字,随便取D(l,r),l>r交换问可能出现的期望.
解法:
暴力.
代码:
#include<bits/stdc++.h>
const int N=1e6;
using namespace std;
int i,head[N+5];
long long ans;
int main()
{
for(scanf("%d",&n),i=1;i<=n;i++)
{
cin>>x;
ans+=(long long)(i-head[x])*(n-i+1)*2;
head[x]=i;
}
ans-=n;
printf("%.12lf",(double)ans/n/n);
return 0;
}
小结:
**此类题目代码十分简单,重在理解。**