第一次双周赛
Reversing Linked List
分数 300
全屏浏览题目切换布局
作者 陈越
单位 浙江大学
Given a constant K and a singly linked list L, you are supposed to reverse the links of every K elements on L. For example, given Lbeing 1→2→3→4→5→6, if K=3, then you must output 3→2→1→6→5→4; if K=4, you must output 4→3→2→1→5→6.
Input Specification:
Each input file contains one test case. For each case, the first line contains the address of the first node, a positive N (≤105) which is the total number of nodes, and a positive K (≤N) which is the length of the sublist to be reversed. The address of a node is a 5-digit nonnegative integer, and NULL is represented by -1.
Then N lines follow, each describes a node in the format:
Address Data Next
where Address
is the position of the node, Data
is an integer, and Next
is the position of the next node.
Output Specification:
For each case, output the resulting ordered linked list. Each node occupies a line, and is printed in the same format as in the input.
Sample Input:
00100 6 4
00000 4 99999
00100 1 12309
68237 6 -1
33218 3 00000
99999 5 68237
12309 2 33218
Sample Output:
00000 4 33218
33218 3 12309
12309 2 00100
00100 1 99999
99999 5 68237
68237 6 -1
代码长度限制
16 KB
时间限制
400 ms
内存限制
64 MB
思路
这道题主要就是修改链表的指向,没有啥思维难度,就是很多细节需要注意
坑
代码实现
#include<iostream>
#include<string>
using namespace std;
const int maxn=1e5+5;
string nor(int n)
{
if(n==-1) return "-1";
int t=0;
int k=n;
string ret="";
while(n>0)
{
n/=10;
t++;
}
if(k==0) t=1;
for(int i=1;i<=5-t;i++) ret+="0";
return ret+to_string(k);
}
struct node
{
int add;
int w;
int next;
}Node[maxn];
void print(node ret[],int len)
{
for(int i=1;i<=len;i++)
{
cout<<nor(ret[i].add)<<" "
<<(ret[i].w)<<" "
<<nor(ret[i].next)<<endl;
}
}
int a[maxn]={};
int main()
{
int begin,num,k;
cin>>begin>>num>>k;
for(int i=1;i<=num;i++)
{
cin>>Node[i].add>>Node[i].w>>Node[i].next;
a[Node[i].add]=i;
}
int now=begin;
node temp[maxn],ret[maxn]={};
int t=0;
while(1)
{
for(int i=1;i<=k;i++)
{
int xh=a[now];
temp[k-i+1+t]=Node[xh];
if(Node[xh].next==-1 && i!=k)
{
for(int j=k;j>=k-i+2;j--)
{
ret[t+k-j+1].add=temp[j+t].add;
ret[t+k-j+1].w=temp[j+t].w;
ret[t+k-j+1].next=temp[j+t].next;
}
ret[t+i].add=temp[k-i+1+t].add;
ret[t+i].w=temp[k-i+1+t].w;
ret[t+i].next=-1;
print(ret,i+t);
exit(0);
}
now=Node[xh].next;
}
for(int i=1;i<=k-1;i++)
{
ret[t+i].add=temp[i+t].add;
ret[t+i].w=temp[i+t].w;
ret[t+i].next=temp[i+1+t].add;
if(temp[i+1+t].add==-1)
{
print(ret,i+1+t);
exit(0);
}
}
ret[t+k].add=temp[k+t].add;
ret[t+k].w=temp[k+t].w;
ret[t+k].next=temp[1+t].next;
if(t>0) ret[t].next=ret[t+1].add;
if(temp[1+t].next==-1)
{
print(ret,k+t);
exit(0);
}
t+=k;
}
return 0;
}
一元三次方程
分数 300
全屏浏览题目切换布局
作者 neuqAcmClub
单位 东北大学秦皇岛分校
给定一个形如a**x3+b**x2+c**x+d=0的一元三次方程。
已知该方程有三个不同的实数根(根与根之差的绝对值≥10−6),且根范围均在[p,q]之间,你需要解出这个方程的三个根。
输入格式:
第一行一个整数T(1≤T≤1000),表示有T组数据
接下来T行,每行6个实数,分别表示a,b,c,d,p,q
数据保证:−102≤p,q≤102,且对于∀x∈[p,q],−106≤f(x)≤106
输出格式:
输出三个实数,表示方程的三个解。
你的答案可以以任意顺序输出。
一个答案被认为是正确的,当且仅当其与标准答案的绝对误差不超过10−6
输入样例:
在这里给出一组输入。例如:
1
1.000000 -5.000000 -4.000000 20.000000 -10.000000 10.000000
输出样例:
在这里给出相应的输出。例如:
-2.000000 2.000000 5.000000
提示1:
样例所给方程的图像如下:
提示2:
对于方程:a**x2+b**x+c=0(Δ=b2−4a**c≥0),它的两个根分别为:x1=2a−b−Δ,x2=2a−b+Δ
代码长度限制
16 KB
时间限制
500 ms
内存限制
128 MB
思路
本来这道题目是可以直接二分的,但是有几组数据得到了加强,所以要按照提示来,先求出两个极值点,然后用三次二分来完成即可
代码实现
#include<iostream>
#include<cmath>
#include<iomanip>
using namespace std;
double mid1,mid2;
double a,b,c,d;
double L=-100,R=100;
void solve1()//求出极值点
{
mid1=(-b-sqrt(b*b-3.0*a*c))/3.0/a;
mid2=(-b+sqrt(b*b-3.0*a*c))/3.0/a;
}
double formula(double x)//方程的左边的值
{
return a*x*x*x+b*x*x+c*x+d;
}
double solve2(double l,double r)//求出x的近似值
{
while(r-l>1e-6)
{
double mid=(l+r)/2;
if(formula(mid)>0 && formula(r)>0 || formula(mid)<0 && formula(r)<0) r=mid;
else l=mid;
}
return l;
}
int main()
{
int T;
cin>>T;
cout<<fixed<<setprecision(6);
while(T--)
{
cin>>a>>b>>c>>d>>L>>R;
if(a<0)
{
a=-a,b=-b,c=-c,d=-d;//为了确保算出来的mid1<mid2
}
solve1();
cout<<solve2(L,mid1)<<" "<<solve2(mid1,mid2)<<" "<<solve2(mid2,R)<<endl;
}
return 0;
}
小结
1、平时那种很繁琐,抠细节的题目还要多练习,感觉这种题目一到考场上,就能压倒一片人,所以这方面的代码基础还要加强。
2、做题目的时候要看提示!!!