题目1 舍友做的,做完后我听了他的描述,自己写了一个解题程序也不知道对不对,毕竟不是在线oj不能查结果。
题目描述,给n,m两个数,n表示球队的个数(从1到n),m表示比赛场数,然后给m组数据,每组数据有两个数,(a,b)即表示a赢了b,要求是输出一种排列方式,使得不存在排在前面的队输过排在后面的队。如果有(a,b)即a一定在b前面。
我的想法是将这m场比赛视为m个不同的规则,初始化一个count数组,长度为n,默认排列顺序为(1…n)然后进行m次检验,如果(a,b)在现有的排列中不满足a在b的前面,则调换a,b的位置,否则不做处理。
我试了下这个方法,发现有的数据不好使。取n=5,m=5五场比赛(2,3)(2,4)(1,2)(1,5)(5,2)
排列的结果:
1 2 3 4 5 比赛(2,3)满足顺序
1 2 3 4 5 比赛(2,4)满足顺序
1 2 3 4 5 比赛(1,2)满足顺序
1 2 3 4 5 比赛(1,5)满足顺序
1 5 3 4 2 比赛(5,2)调整2,5位置 但是在这个地方会使2排在3 4后面,以至于不满足前面的规则。
随后进行了改进,把这个循环写成一个函数,sort进行排序,排序完后进行test,检查现在的结果是否满足要求,如果不满足,再进行一次sort,若干次排序后一定会得到一个结果满足条件。
代码如下:
#include <iostream>
using namespace std;
void soft(int count[],int a[][2], int m, int n)
{
for(int i = 0; i < m; i++)
{
int j,k,temp;
for(j = 0; j < n; j++)
{
if(count[j] == a[i][0])
{
break;
}
}
for(k = 0; k < n; k++)
{
if(count[k] == a[i][1])
{
break;
}
}
if(j > k)
{
temp = count[j];
count[j] = count[k];
count[k] = temp;
}
}
}
bool test(int count[], int a[][2], int m, int n)
{
for(int i = 0; i < m; i++)
{
int j,k;
for(j = 0; j < n; j++)
{
if(count[j] == a[i][0])
{
break;
}
}
for(k = 0; k < m; k++)
{
if(count[k] == a[i][1])
{
break;
}
}
if(j > k)
{
return false;
}
}
return true;
}
int main()
{
int n,m;
cin>>n>>m;
int a[m][2];
for(int i = 0; i < m ; i++)
{
cin>>a[i][0]>>a[i][1];
}
int count[n];
for(int i = 0; i < n; i++)
{
count[i] = i+1;
}
while(!test(count,a,m,n))
{
soft(count,a,m,n);
}
for(int i = 0; i < n; i++)
{
cout<<count[i]<<" ";
}
return 0;
}
可能还是会有些情况没有考虑到,但是因为这个不是提交就能看结果的测评,所以没办法去验证。
题目2 给一个数组a={8,3,5,2,7,4,6,1},要求用O(n)的时间复杂度,O(1)的空间复杂度做。
做法:申请一个count数组(所有元素为0),保证数组的长度大于要排序的数组的最大元素,然后遍历数组a,把a中每一个元素的值做为count数组的下标,并使该下标对应的数组元素的值自增。用空间换取时间的非典型排序方法。
代码如下:
#include <iostream>
using namespace std;
void sort(int count[], int a[], int len)
{
for(int i = 0; i < len; i++)
{
count[a[i]]++;
}
for(int i = 0, j = 0; i < 65536; i++)
{
if(count[i] != 0)
{
a[j++] = i;
count[i]--;
i--;
}
}
}
void show(int a[], int len)
{
for(int i = 0; i < len; i++)
{
cout<<a[i]<<" ";
}
}
using namespace std;
int main()
{
int count[65536] = {0};
int a[] = {8,3,5,2,7,4,6,1};
int len = sizeof(a)/sizeof(int);
sort(count,a,len);
show(a,len);
return 0;
}
顺便上 http://www.cspro.org/lead/application/ccf/login.jsp 查了一下 第十次CCF CSP认证成绩
强烈建议做成在线oj模式,每次提交得让我知道我过了多少样例啊!
这个认证其实没什么用(个人感觉),当时只是怀着反正免费报名,那就去玩一玩的态度去的,我查了一下我上一次报名是15年9月份的时候,那时是第五次,一年三次,4/9/12这样,那次因为临时有事,没去考。基本前两题就是送分题,基本学过点语言知识的都会做,后面三基本是没有花时间刷题很难自己想出来的,即使学了算法什么的。其实很好奇第三题为什么只有0分,可能是我的输出格式不对,第四题难道是我用递归的方法超时了?其实是个用动态规划解的题,第五题我是随便写的,反正当时的样例我试了能过两。
其实一直以来我都觉得没有参加ACM是我上大学最失败的事情啊啊啊啊啊啊~~~