​cf题目链接​

​计蒜客题目链接​

​献上官方题解​

注意cf和计蒜客的输出格式是不一样的,我在cf能A的,就没去计蒜客验证了

A-Find the Twins

UCF Locals 2015(A~I(竞赛图+哈密顿回路))_#include

水题 注意输出格式就行了。

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=(b);++i)
#define mem(a,x) memset(a,x,sizeof(a))
#define pb push_back
#define pi pair<int, int>
#define mk make_pair
using namespace std;
typedef long long ll;
ll gcd(ll a,ll b) { return b?gcd(b,a%b):a;}
const int N=12;
int a[N],n;
int main()
{
int _;cin>>_;while(_--)
{
n=10;
int f=0,f1=0;
for(int i=1;i<=10;++i){
int x;
scanf("%d",&x);
if(x==17) f=1;
if(x==18) f1=1;
a[i]=x;
}
rep(i,1,10) {
if(i==1) printf("%d",a[i]);
else printf(" %d",a[i]);
}
puts("");
if(f&&f1) puts("both");
else if(!f&&f1) puts("mack");
else if(f&&!f1) puts("zack");
else puts("none");
puts("");
}
}



B-Medal Ranking

UCF Locals 2015(A~I(竞赛图+哈密顿回路))_#define_02

还是签到题,注意输出格式即可。

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=(b);++i)
#define mem(a,x) memset(a,x,sizeof(a))
#define pb push_back
#define pi pair<int, int>
#define mk make_pair
using namespace std;
typedef long long ll;
ll gcd(ll a,ll b) { return b?gcd(b,a%b):a;}
const int N=12;
int a[N],n;
int main()
{
int _;cin>>_;while(_--)
{
int a,b,c;
int x,y,z;
scanf("%d%d%d%d%d%d",&a,&b,&c,&x,&y,&z);
int f=0,f1=0;
if(a+b+c>x+y+z) f=1;
if(a>x||a==x&&b>y||a==x&&b==y&&c>z) f1=1;
printf("%d %d %d %d %d %d\n",a,b,c,x,y,z);
if(f&f1) puts("both");
else if(f) puts("count");
else if(f1) puts("color");
else puts("none");
puts("");
}
}

C-Brownies vs. Candies vs. Cookies

模拟题 ,看懂题意模拟一下就可以了

UCF Locals 2015(A~I(竞赛图+哈密顿回路))_#define_03

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=(b);++i)
#define mem(a,x) memset(a,x,sizeof(a))
#define pb push_back
#define pi pair<int, int>
#define mk make_pair
using namespace std;
typedef long long ll;
ll gcd(ll a,ll b) { return b?gcd(b,a%b):a;}
const int N=1e5+10;
int a[N],n;
int main()
{
int cas=0;
int _;cin>>_;while(_--)
{
int d,ans;

scanf("%d%d",&d,&ans);
int t=ans;
int m;
scanf("%d",&m);
for(int i=1;i<=m;++i){
scanf("%d",&a[i]);
}
printf("Practice #%d: %d %d\n",++cas,d,t);
for(int i=1;i<=m;++i){
if(ans-a[i]>0){
ans-=a[i];
}
else{
while(ans-a[i]<=0) ans=2*ans;
ans-=a[i];
}
printf("%d %d\n",a[i],ans);

}
puts("");
}
}

D-Lemonade Stand

UCF Locals 2015(A~I(竞赛图+哈密顿回路))_c++_04

水题,模拟一下即可。

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=(b);++i)
#define mem(a,x) memset(a,x,sizeof(a))
#define pb push_back
#define pi pair<int, int>
#define mk make_pair
using namespace std;
typedef long long ll;
ll gcd(ll a,ll b) { return b?gcd(b,a%b):a;}
const int N=1e3+10;
ll n,d,x;
struct node
{
ll c,pl,ps;
}a[N];
ll sum[N],dp1[N];
int main()
{
int cas=0;
int _;cin>>_;
for(int kk=1;kk<=_;++kk)
{
scanf("%d%d%d",&n,&d,&x);
for(int i=1;i<=n;++i){
scanf("%lld%lld%lld",&a[i].c,&a[i].pl,&a[i].ps);
sum[i]=sum[i-1]+a[i].c;
dp1[i]=(1ll<<62);
}

for(int i=1;i<=n;++i){
for(int j=1;j<=i;++j){
ll t=sum[i]-sum[j-1];
t=t*d;
t=t*a[j].pl;
dp1[i]=min(dp1[i],t+dp1[j-1]);
}
}

// rep(i,0,n){
// printf("i:%d dp:%lld\n",i,dp1[i]);
// }
ll to=0;
ll ans=0;
int j;
for(int i=1;i<=n;)
{
for(j=i+1;j<=n;++j){
if(a[j].ps<a[i].ps){
break;
}
}
--j;
ll s=sum[j]-sum[i-1];
s=s*x;//需要的蛊司

ll t1=0;
while(to<s){
to+=80;
t1++;
}

ans+=t1*a[i].ps;//价格
to=to-s;
i=j+1;
}
//printf("%lld %lld %lld\n",dp1[n],ans,dp1[n]+ans);
if(kk!=_) printf("%lld\n",dp1[n]+ans);
else printf("%lld",dp1[n]+ans);
}

E-Rain Gauge

UCF Locals 2015(A~I(竞赛图+哈密顿回路))_#define_05

这题 有一个不错的博客,有图 ​

UCF Locals 2015(A~I(竞赛图+哈密顿回路))_c++_06

#include<stdio.h>
#include<math.h>
#define pi 3.14159265358979
int main()
{
int n;
double s,r;
scanf("%d",&n);
while(n--)
{
scanf("%lf%lf",&s,&r);
if(s>=2*r)printf("%.2lf\n",pi*r*r);
else if(2*r>=sqrt(2*s*s))printf("%.2lf\n",s*s);
else
{
double angle,sector,triangle;
angle=acos(s/2/r);
sector=2*angle*r*r/2;
triangle=r*r*sin(2*angle)/2;
printf("%.2lf\n",pi*r*r-4*(sector-triangle));
}
}
}

F-Balanced Strings

UCF Locals 2015(A~I(竞赛图+哈密顿回路))_#define_07

从这题开始才有点质量了。

题意:给你一个字符串,?  代表 你可以填字母,要求所有长度为偶数的子串  中的元音字符等于辅音字符,这里设 y也为元音

做法:仔细想想就知道是 元辅 交叉才符合题目

设dp[i][0]为当前位置为元音字母时的方案数

设dp[i][1]为当前位置为辅音字母时的方案数

dp一下即可。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e2+10;
char s[N];
int n;
ll dp[N][2];
bool check(char c)
{
if(c=='a'||c=='o'||c=='e'||c=='i'||c=='u'||c=='y') return 1;
return 0;
}
int main()
{
int cas=0;
int _;cin>>_;while(_--)
{
scanf("%s",s+1);
n=strlen(s+1);
dp[0][0]=dp[0][1]=1;
for(int i=1;i<=n;++i){
if(s[i]=='?'){
dp[i][0]=1ll*6*dp[i-1][1];
dp[i][1]=1ll*20*dp[i-1][0];
}
else{
dp[i][0]=dp[i][1]=0;
if(check(s[i])) dp[i][0]=dp[i-1][1];
else dp[i][1]=dp[i-1][0];
}
}
printf("String #%d: ",++cas);
printf("%lld\n",dp[n][0]+dp[n][1]);
puts("");
}
}
/*
7
orooji
al?
a?i
g?ha
a?u?
?????????????????
arup
*/

G-Towers of Hanoi Grid

UCF Locals 2015(A~I(竞赛图+哈密顿回路))_#include_08

题意:输入d,n 代表n*n的矩阵地图。(1,1)位置有d个 的汉诺塔,每次只能走x+1  或y+1的格子。问最少几步把汉诺塔移到(n,n)

做法:我们都知道,三个柱子才能使得汉诺塔进行移动,那么这题不存在有三个柱子可以互相到达。

那么点拨了一个思路:除了最后一个大得,上面小的分布在(n-1)*(n-1)上,最好留出一行一列给最后一个大的走到(n,n);

那么只需要判断(n-1)*(n-1)与d-1的大小 即可,然后答案就是d个曼哈顿距离 d*(n-1+n-1)

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

int main()
{
int t;
cin>>t;
int cas=0;
while(t--){
ll a, b;
cin>>a>>b;
ll mx = (b*b - 2*b + 2);
printf("Grid #%d: ",++cas);
if(a<=mx) printf("%lld\n",a*(2*b-2));
else puts("impossible");
puts("");
}
}

H-Reach for the Stars

UCF Locals 2015(A~I(竞赛图+哈密顿回路))_#include_09

题意:输入n*m的字符矩阵,每次可以用十字型的盖章对#进行覆盖,只能覆盖#部分,问最少使用几次十字印章才能将所有的 # 字符都至少覆盖一次。

做法:以为是简单的判断一下,没想到一直wa,由于n<=9 而且时间是2.5s  很显然,这题需要DFS爆搜。

枚举十字印章中间那么点所在的位置 递归回溯一下 能否全部覆盖,然后加了很多很多剪枝才过的。

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
using namespace std;

char Map[10][10];
int T,N,M,Ans,Case=0;

void DFS(int i,int j,int Step,int Count){
printf("i:%d j:%d\n",i,j);
if(Step>=Ans) return;//常见剪枝
if(Count==0){Ans=min(Ans,Step);return;}
if(i==1 || i>=N || j==1 || j>=M) return;

if((Count-1)/5+1+Step>=Ans) return;//优化1

char temp[5];
int Cnt=0;
bool flag=false;

temp[0]=Map[i][j];
temp[1]=Map[i-1][j];
temp[2]=Map[i+1][j];
temp[3]=Map[i][j-1];
temp[4]=Map[i][j+1];
for(register int k=0;k<5;++k){
if(temp[k]=='#') ++Cnt;
if(temp[k]=='.'){flag=true;break;}
}
if(!flag && Cnt){
Map[i][j]=Map[i-1][j]=Map[i+1][j]=Map[i][j-1]=Map[i][j+1]='@';
if(j+1<M) DFS(i,j+1,Step+1,Count-Cnt);//递归回溯下
else DFS(i+1,2,Step+1,Count-Cnt);
Map[i][j]=temp[0];
Map[i-1][j]=temp[1];
Map[i+1][j]=temp[2];
Map[i][j-1]=temp[3];
Map[i][j+1]=temp[4];
}
if(i==2 && Map[1][j]=='#') return;//优化2 这四种情况没必要进行后面的递归回溯了
if(j==2 && Map[i][1]=='#') return;
if(i==N-1 && Map[N][j]=='#') return;
if(j==M-1 && Map[i][M]=='#') return;

if(j+1<M) DFS(i,j+1,Step,Count);
else DFS(i+1,2,Step,Count);
return;
}

int main(){
ios::sync_with_stdio(false);
cin>>T;
while(T--){
++Case;
cout<<"Image #"<<Case<<": ";
cin>>N>>M;
Ans=2147483647;
int Count=0;
for(register int i=1;i<=N;++i){
for(register int j=1;j<=M;++j){
cin>>Map[i][j];
if(Map[i][j]=='#') ++Count;
}
}
if(Map[1][1]=='#'||Map[1][M]=='#'||Map[N][1]=='#'||Map[N][M]=='#'){
cout<<"impossible"<<endl;
continue;
}
DFS(2,2,0,Count);
if(Ans==2147483647) cout<<"impossible"<<endl;
else cout<<Ans<<endl;
cout<<endl;
//puts("")
}

return 0;
}
/*
9 6
.##...
####..
.##...
......
......
......
.#....
###...
.#....
*/

I-Longest Path

献上官方题解,我是真不太会

UCF Locals 2015(A~I(竞赛图+哈密顿回路))_c++_10

很妙的做法,竞赛图中医定存在哈密顿回路,这个也是一个知识点了

#include<bits/stdc++.h>
using namespace std;
const int N=5e2+10;
int mp[N][N],n;

int main()
{
int _;cin>>_;while(_--)
{
scanf("%d",&n);
for(int i=1;i<=n;++i)
for(int j=1;j<=n;++j)
{
scanf("%d",&mp[i][j]);
if(mp[i][j]==0) mp[j][i]=1;
}

deque<int>que;
que.push_back(1);
for(int i=2;i<=n;++i){
int in=0,out=0;
for(auto it:que){
if(mp[i][it]) out++;//若????连向 list 中的所有点,则把????加入 list 的头部。
else in++;//若 list 中的所有点连向????,则把????加入 list 的尾部。
}

if(in==-1) que.push_back(i);
else if(out==i-1) que.push_front(i);
else{
auto it=que.begin();
for(;it!=que.end();it++){
auto ne=it;++ne;
if(ne==que.end()) break;
if(mp[*it][i]&&mp[i][*ne]) break;
}
que.insert(++it,i);
}
}

int num=1;
for(int v:que) {
if(num==1)
printf("%d",v);
else
printf(" %d",v);
num++;
}
puts("");

}
return 0;
}