前言
今天一早就蹦了起来,不知道干嘛了,看见宿友还在Sleeping,我情不自禁又躺下了,唉,好苦啊·······
今天做了四道题
第一题
题目大意
在n * n *n的立方体中放n个子,有多少种布子方案可以使这n个子连成一条线…
输出为一个正整数,它表示在n3的立方体中n个格子连成一条直线的方案数…
输入样例
2
输出样例
28
解题思路
自己画的,比较丑
其实一开始是我看这道题是比较懵逼的,又来才知道可以这样求
就是在这个立体方格中,要求出它的竖排,横排和斜排…然后就可以先推出…让每行,列,斜的方格外补充一些立体方格,然后就推出了补充的了体积,再最后把统计出的公式,如下:
也可以简便,这里我就不详细说明
程序如下
有点水
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
int n;
int main()
{
freopen("tictac.in","r",stdin);
freopen("tictac.out","w",stdout);
scanf("%d",&n);
printf("%d",((n+2)*(n+2)*(n+2)-n*n*n)/2);//公式
fclose(stdin);
fclose(stdout);
return 0;
}
第二题
题目大意
在n个人中,某些人的银行账号之间可以互相转账。给定这些人之间转账时需要从转账金额里扣除百分之几的手续费,请问A最少需要多少钱使得转账后B收到100元…
输入样例
3 3
1 2 1
2 3 2
1 3 3
1 3
输出样例
103.07153164
解题思路
例如:
其实这道题就是求出最短的路径,但是要求最大的值.
最后再用100除于它就可以了
这题我是用Dijkstra算法来做的
程序如下
#include<cstdio>
#include<cmath>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
int n,m,q,x,y;
double f[3001][3001],z,p,a[3001],b[3001];
int main()
{
freopen("money.in","r",stdin);
freopen("money.out","w",stdout);
scanf("%d %d",&n,&m);
for (int i=1;i<=m;i++)
{
scanf("%d %d %lf",&x,&y,&z);
f[x][y]=f[y][x]=(100-z)/100;//求每条路径的z%的手续费
}
scanf("%d %d",&x,&y);
for (int i=1;i<=n;i++)
{
b[i]=f[x][i];//替换
}
b[x]=1;//赋值
a[x]=true;//标记
for (int i=2;i<n;i++)
{
p=0;
q=0;
for (int j=1;j<=n;j++)
if ((!a[j])&&(b[j]>p))//判断是否走过
{
p=b[j];//替换
q=j;
}
a[q]=true;
for (int j=1;j<=n;j++)
if ((!a[j])&&(b[q]*f[q][j]>b[j]))//判断是否有其它路径比它还短
b[j]=b[q]*f[q][j];//如果有就替换
}
printf("%.8lf",100/b[y]);
fclose(stdin);
fclose(stdout);
return 0;
}
第三题
题目大意
输入一个正整数S…输出最大的约数之和…
输入样例
11
输出样例
9
解题思路
首先要判断s是否等于1
再一个个数枚举,判断是否整除
如果可以就存起来,再求出最大的约数
程序如下
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int c,a,s,b[10001],d[10001];
int qq(int t)
{
if(t==1)//特殊情况
{
return 0;
}
c=1,a=t;
for(int i=2;i<t;i++)
{
if(!(a%i))//判断是否能整除
{
c+=i;
}
}
return c;
}
int main()
{
freopen("maxsum.in","r",stdin);
freopen("maxsum.out","w",stdout);
scanf("%d",&s);
for(int i=1;i<=s;i++)
b[i]=qq(i);//返回值
for(int i=1;i<=s;i++)
for(int j=s;j>=i;j--)
{
d[j]=max(d[j-i]+b[i],d[j]);//求最大的
}
printf("%d",d[s]);
fclose(stdin);
fclose(stdout);
return 0;
}
第四题
题目大意
第一行输入两个用空格隔开的正整数m和n,分别代表表格的列数和行数。
第二行输入一个正整数s,表示操作的总数。
以下s行每行输入一个操作,
1.每个操作占一行,根据操作类型的不同,每行中可能有二至四个用空格隔开的“单词”;
2.每行的第一个单词指定了该操作涉及的单元格的位置;
3.每行的第二个单词指定了相应的操作,可能是: input,output,sum,avg
(1).如果第二个单词是input,表示接下来的一个整数是要赋予该单元格的值,这个值是
不超过1000的正整数
(2).如果第二个单词是output,表示你需要在输出文件中输出这个单元格当前的值
(3).如果第二个单词是sum,表示接下来输入的两个单词定义了一个矩形区域,该单元格的值就应该恒为这个矩形区域中所包含的单元格的值的和,直到该单元格被重新定义
(4).如果第二个单词是avg,表示接下来输入的两个单词定义了一个矩形区域,该单元格的值就应该恒为这个矩形区域中所包含的单元格的值的算术平均数,直到该单元格被重新定义;
…对于输入数据的每一个“ output”操作输出一行结果。因此,输出文件的行数等于输入文
件中“ output”操作的个数。
输入样例
3 5
5
A1 input 100
B2 input 200
C3 sum A1 C2
C5 avg B2 C4
C5 output
输出样例
83
解题思路
如图:
这题就是用递归来不断的进入每一个的矩阵来执行,直到没有得执行才退出