这周终于上300分了。。然而其实400是挺稳的。。。
犯了一些玄学错误(递归爆栈,搜索变贪心。。。。)
本来预计得分是100+100+100+100+30+10=440的。。。@Siyuan最强啦
T1:
洛谷原题,USACO的佬(没有打错)题了。。。
枚举最小山峰的高度,然后把所有山都修建成符合条件的区间内的山即可
code:
#include<bits/stdc++.h>
using namespace std;
int n,a[1010];
int ans=1e9,cnt;
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++)scanf("%d",&a[i]);
for(int h=0;h<=100;h++){
cnt=0;
for(int i=1;i<=n;i++){
if(a[i]>h) cnt+=(a[i]-h)*(a[i]-h);
if(a[i]<h-17) cnt+=(h-17-a[i])*(h-17-a[i]);
}
ans=min(ans,cnt);
}
printf("%d",ans);
return 0;
}
T2:
洛谷原题,USACO佬题(还是没有打错。。)。。。
首先考虑模拟,然后把时间和距离分开来处理就好了呀。。。
code:
#include<bits/stdc++.h>
#define ll long long
using namespace std;
char ch;
double last,ans;
int d[10010],t[10010];
int n,x,now=1;
int nt,nd,cnt=1;
int main(){
d[++nd]=0;
d[++nd]=1000;
scanf("%d",&n);
for(int i=1;i<=n;i++){
getchar();
scanf("%c%d",&ch,&x);
if(ch=='T') t[++nt]=x;
else d[++nd]=x;
}
sort(d+1,d+nd+1);
sort(t+1,t+nt+1);
for(int i=1;i<nd;i++){
last=d[i];
while(last<d[i+1]&&now<=nt&&ans+(d[i+1]-last)*cnt>t[now]){
last+=(t[now]-ans)/cnt;
cnt++;
ans=t[now++];
}
ans+=(d[i+1]-last)*cnt;
cnt++;
}
printf("%.0lf\n",ans);
return 0;
}
T3:
4^12次的爆搜,然而我却忘记了每组都要3头牛。。。
后来想起来,但是想到这样会导致答案不优,就懒得改了。。。(woc懒癌晚期了。。)
然而发现这样是错的。。。
code:
#include<bits/stdc++.h>
using namespace std;
int b[5],a[20];
int ans=1e9;
void dfs(int dep,int cnt1,int cnt2,int cnt3,int cnt4){
if(dep>12){
ans=min(ans,max(max(cnt1,cnt2),max(cnt3,cnt4))-min(min(cnt1,cnt2),min(cnt3,cnt4)));
return;
}
if(b[1]<3){
b[1]++;
dfs(dep+1,cnt1+a[dep],cnt2,cnt3,cnt4);
b[1]--;
}
if(b[2]<3){
b[2]++;
dfs(dep+1,cnt1,cnt2+a[dep],cnt3,cnt4);
b[2]--;
}
if(b[3]<3){
b[3]++;
dfs(dep+1,cnt1,cnt2,cnt3+a[dep],cnt4);
b[3]--;
}
if(b[4]<3){
b[4]++;
dfs(dep+1,cnt1,cnt2,cnt3,cnt4+a[dep]);
b[4]--;
}
return;
}
int main(){
for(int i=1;i<=12;i++)scanf("%d",&a[i]);
dfs(1,0,0,0,0);
printf("%d",ans);
return 0;
}
T4:
一开始想到最小生成树。。。然后赛后验证发现爆零。。(还好没有写。。)
想到了二分+DFS来判断最小答案。。。
然而痛苦地爆栈我也很绝望。。。。(早知道写queue的广搜了。。。)
code:
#include<bits/stdc++.h>
#define pii pair<int,int>
#define fi first
#define se second
#define pb push_back
#define mk make_pair
using namespace std;
int m,n,ans,tot,vis[510][510];
vector<pii > mp;
int h[510][510],x,t;
void dfs(int x,int y,int tot){
if(x<1||x>n||y<1||y>m) return;
if(vis[x][y]) return;
vis[x][y]=1;
if(abs(h[x-1][y]-h[x][y])<=tot) dfs(x-1,y,tot);
if(abs(h[x+1][y]-h[x][y])<=tot) dfs(x+1,y,tot);
if(abs(h[x][y-1]-h[x][y])<=tot) dfs(x,y-1,tot);
if(abs(h[x][y+1]-h[x][y])<=tot) dfs(x,y+1,tot);
return;
}
bool check(int d){
dfs(mp[0].fi,mp[0].se,d);
bool flag=true;
for(int i=0;i<mp.size();i++)if(!vis[mp[i].fi][mp[i].se]) flag=false;
return flag;
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
scanf("%d",&h[i][j]);
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++){
scanf("%d",&x);
if(x==1) mp.pb(mk(i,j));
}
int l=0,r=1e9;
while(l<=r){
int mid=l+r>>1;
memset(vis,0,sizeof(vis));
if(check(mid)) r=mid-1,ans=mid;
else l=mid+1;
}
printf("%d",ans);
return 0;
}
T5:
这题的线段树+扫描线实在是太♂骚了。。。。
于是只打了个n^3的暴力,骗了30分。。。。
code:
#include<bits/stdc++.h>
using namespace std;
int mp[1010][1010];
int n,a,x,b,y;
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d%d%d%d",&x,&y,&a,&b);
x+=200;
y+=200;
for(int j=x;j<=x+a-1;j++)
for(int ij=y;ij<=y+b-1;ij++)
mp[j][ij]=1;
}
int ans=0;
for(int i=0;i<=1000;i++)
for(int j=0;j<=1000;j++)
ans+=mp[i][j];
printf("%d",ans);
return 0;
}
T6:
这题标算很♂玄学。。。
于是打了个@Siyuan教我的骗分
就是输出样例和10.。。。(样例特判。。)
竟然能拿40分!!!太神了!!!比暴力还高!!!!
code:
#include<bits/stdc++.h>
using namespace std;
int n,m;
int main(){
scanf("%d%d",&n,&m);
if(n==3&&m==6) puts("3");
else puts("10");
return 0;
}