Problem Description
蜘蛛牌是windows xp操作系统自带的一款纸牌游戏,游戏规则是这样的:只能将牌拖到比她大一的牌上面(A最小,K最大),如果拖动的牌上有按顺序排好的牌时,那么这些牌也跟着一起移动,游戏的目的是将所有的牌按同一花色从小到大排好,为了简单起见,我们的游戏只有同一花色的10张牌,从A到10,且随机的在一行上展开,编号从1到10,把第i号上的牌移到第j号牌上,移动距离为abs(i-j),现在你要做的是求出完成游戏的最小移动距离。
Input
第一个输入数据是T,表示数据的组数。
每组数据有一行,10个输入数据,数据的范围是[1,10],分别表示A到10,我们保证每组数据都是合法的。
Output
对应每组数据输出最小移动距离。
Sample Input
1
1 2 3 4 5 6 7 8 9 10
Sample Output
9
这道题在比赛的时候感觉到是搜索了,奈何我的搜索学的宛如一个智障。。。。。
因为题中说的很明白1只能叠加到2上,2只能叠加到3上… … …以此类推,所以我们搜索的是叠加的顺序,比如简单一点3个数1 2 3:我们深度搜索的是,1先叠加到2上然后2再叠加到3上,还是,2先叠加到3上然后1再叠加到3上;再搜索的时候注意剪枝
#include
#include
#include
using namespace std;
int a[15],vis[15];
int sum;
void dfs(int cnt,int ans)
{
if(cnt==9)
sum=min(ans,sum);
if(ans>sum)
return ;
for(int i=1;i<10;i++)
{
if(!vis[i])
{
vis[i]=1;
for(int j=i+1;j<=10;j++)
{
if(!vis[j])
{
dfs(cnt+1,ans+abs(a[i]-a[j]));
break;
}
}
vis[i]=0;
}
}
}
int main()
{
int T,x;
scanf("%d",&T);
while(T--)
{
memset(vis,0,sizeof(vis));
memset(a,0,sizeof(a));
for(int i=1;i<=10;i++)
{
scanf("%d",&x);
a[x]=i;
}
sum=0x3f3f3f3f;
dfs(0,0);
printf("%d\n",sum);
}
return 0;
}
具体题解看单发博客
B题
·
·
·
就不复制英文题意了
大概题意是给你两个长方形的长宽a,b,x,y,问你第二个长方形能不能放进第一个长方形(坑点为不能完完全全的覆盖,只要有一点没有碰到就行)
也就是比较h和a的大小,当h
#include
#include
#include
#include
using namespace std;
int f(double a,double b,double x,double y)
{
double k=sqrt(x*x+y*y);
double j=acos(y/k)-acos(b/k);
double h=y*sin(j)+x*cos(j);
if(h<a)
return 1;
return 0;
}
int main()
{
double a,b,x,y;
int T;
scanf("%d",&T);
while(T--)
{
scanf("%lf %lf %lf %lf",&a,&b,&x,&y);
if(a<b)
swap(a,b);
if(x<y)
swap(x,y);
if(a>x&&b>y)
{
printf("Escape is possible.\n");
continue;
}
else if(y>b||a*b<=x*y)
{
printf("Box cannot be dropped.\n");
continue;
}
else
{
if(f(a,b,x,y))
printf("Escape is possible.\n");
else
printf("Box cannot be dropped.\n");
}
}
return 0;
}
题目太长就不复制了(比赛的时候,英语真的是个硬伤,看样例猜到了是最短路,奈何英语是个硬伤,没看出具体的题意。。。。很难受)
大概题意:n个点m条有向边,每条边有一个权值,问你从点1到其他所有点,再从其他所有点返回到点1所要花费的最小值
其实就是从1点跑一个最短路,然后反向存边,再跑一遍最短路
#include
#include
#include
#include
using namespace std;
int tot;
int f[1000005],book[1000005];
struct node
{
int u,v,w;
};
node a[1000005];
struct node1
{
int v,w,nex;
};
node1 e[1000005];
long long dis[1000005];
const long long inf=9223372036854775807;
void init(int n)//所需变量初始化
{
tot=0;
for(int i=0;i<=n+2;i++)
{
dis[i]=inf;
book[i]=0;
f[i]=-1;
}
}
void add(int u,int v,int w)//邻接表存边
{
e[tot].v=v;
e[tot].w=w;
e[tot].nex=f[u];
f[u]=tot++;
}
void spfa()//最短路
{
queue<int>q;
q.push(1);
book[1]=1;
dis[1]=0;
while(!q.empty())
{
int u=q.front();
q.pop();
for(int i=f[u]; i!=-1; i=e[i].nex)
{
int v=e[i].v;
if(dis[v]>dis[u]+e[i].w)
{
dis[v]=dis[u]+e[i].w;
if(book[v]==0)
{
q.push(v);
book[v]=1;
}
}
}
book[u]=0;
}
}
int main()
{
int n,m,T;
scanf("%d",&T);
while(T--)
{
scanf("%d %d",&n,&m);
init(n);
for(int i=1; i<=m; i++)
{
scanf("%d %d %d",&a[i].u,&a[i].v,&a[i].w);
add(a[i].u,a[i].v,a[i].w);
}
spfa();
long long sum=0;
for(int i=1;i<=n;i++)
sum+=dis[i];
init(n);
for(int i=1;i<=m;i++)//反向存边
add(a[i].v,a[i].u,a[i].w);
spfa();
for(int i=1;i<=n;i++)
sum+=dis[i];
printf("%lld\n",sum);
}
return 0;
}
·
·
看不懂题意是真的伤。。。比赛完用百度翻译看题还是没搞懂题意是啥。。。。绝了。。。
大概题意:有1-n个格子,a艘船,每个船要占连续b个格子,已经确定有k个格子没有船,那么每次射击一个格子,最少要射击多少次一定能射击到一个船。
我们先算出来一共最多可以放cnt条船(记录一下每条船的位置),那么我们把这nun条船射击到只剩a-1条船,就一定射击到了一条船
#include
#include
#include
using namespace std;
char s[200005];
int ans[200005];
int main()
{
int n,a,b,k;
while(~scanf("%d %d %d %d",&n,&a,&b,&k))
{
memset(ans,0,sizeof(ans));
int t=0,cnt=0;
scanf("%s",s+1);
for(int i=1;i<=n;i++)
{
if(s[i]=='1')
t=0;
else
t++;
if(t%b==0&&t!=0)
{
ans[cnt++]=i;
}
}
printf("%d\n",cnt-a+1);
for(int i=0;i<cnt-a+1;i++)
printf("%d ",ans[i]);
printf("\n");
}
return 0;
}
·
·
题意:有一个n*n的方格,开始的时候每个格子都是空的,两个人轮流在方格纸中选一个格子涂上一个颜色,涂的每个格子和之前涂的格子不能有相同的边,问如果是你,当n不同的时候,选择先涂还是后涂可以赢
简单博弈,当n为奇数的时候,所能涂的格子是奇数,所以先涂,偶数的时候能涂的格子数是偶数,所以后涂
#include
#include
#include
using namespace std;
int main()
{
long long n;
while(~scanf("%lld",&n))
{
if(n%2)
printf("1\n");
else
printf("2\n");
}
return 0;
}
·
·
题意就是:F(1) = 1, F(2) = 1, F(3) = 1,F(4) = 1, F(n>4) = F(n - 1) + F(n-2) + F(n-3) + F(n-4)
让你算第n个数
当时比赛的时候,电脑上没有java的编译器。。。然后我硬盒的用cb打了个java,结果就是不停的CE,反正最后A掉了。。。也是很绝望
import java.math.BigInteger;
import java.util.Scanner;
public class Main{
public static void main(String[] args){
Scanner in = new Scanner(System.in);
BigInteger a[] = new BigInteger[10005];
BigInteger y = new BigInteger("1");
a[1]=y;
a[2]=y;
a[3]=y;
a[4]=y;
for(int i=5;i<=10000;i++){
BigInteger x = new BigInteger("0");
x=x.add(a[i-1]);
x=x.add(a[i-2]);
x=x.add(a[i-3]);
x=x.add(a[i-4]);
a[i]=x;
}
while(in.hasNext()){
int n=in.nextInt();
System.out.println(a[n]);
}
}
}
·
·
大概题意:有一个1-n的数轴,m个区间【a,b】,每个区间覆盖了一个颜色,问最后在数轴上还有哪些点没有被覆盖
看了一下n,m的取值范围是100,然后就直接暴力模拟了
#include
#include
#include
using namespace std;
int a[1005];
int b[1005];
int main()
{
int n,m;
while(~scanf("%d %d",&n,&m))
{
memset(a,0,sizeof(a));
int x,y;
for(int i=1;i<=n;i++)
{
scanf("%d %d",&x,&y);
for(int j=x;j<=y;j++)
a[j]=1;
}
int sum=0;
for(int i=1;i<=m;i++)
{
if(!a[i])
b[sum++]=i;
}
printf("%d\n",sum);
for(int i=0;i<sum;i++)
printf("%d%c",b[i],i==sum-1?'\n':' ');
if(sum==0)
printf("\n");
}
return 0;
}
这场比赛打得我。。。内心很是绝望。。B题知道是数位dp没有的打出来,然而也没有记板子(再不记板子我是狗。。。。)后面的题基本都是板子题。。。英语太差。。。A题的深搜其实也很简单,但是没有写出来。。。。反正就是还是很菜。。。(哭唧唧)