吃透这本书?吃透这本书。
第一章
库函数:(历史沉淀下来的大智慧)
常用的有pow,sqrt,abs……。这其实挺能引起我们深思的,就是这些函数背后隐藏着什么,靠什么方法实现的?
sqrt():
(1)、开根号我们不知道怎么求,但是我们可以猜答案啊!脑袋里第一个思路就是二分,话不多说,开工。
#define eps 1e-8
double sqrt(double x){
double L=0,R,M;
if(x>1)R=x;
else if(x==1)return 1;
else if(x>=0)R=1;
else{puts("ERROR,can't sqrt(nagative)!");return -1;}
while(R-L>eps){
M=(L+R)/2;
if(M*M<x)L=M;
else R=M;
}
return M;
}
然而这个有点太慢了。
(2)、牛顿迭代。
就是这个东东,主要用来求高阶方程,当然,求平方根也适用。
它的原理就是用切线一直逼近。
就像这个图,求
,也就是求
函数与x轴焦点,就这样一直逼近就好了。在这里求平方根的公式就变成了
。
#define eps 1e-8
double my_sqrt(double x){
double last,now=x;
do{
last=now;
now=(now+x/now)/2;
}while(abs(now-last)>eps);
return now;
}
但是还是稍微有一点点慢。
(3)、黑科技 神秘数字0x5f3759df
只不过这个快是快,准确度差了一些。system应该用的不是这个吧,,
float my_sqrt(float x){
float xhalf =0.5f*x;
int i=*(int*)&x;
i=0x5f375a86- (i>>1);
x=*(float*)&i;
x=x*(1.5f-xhalf*x*x);
x=x*(1.5f-xhalf*x*x);
x=x*(1.5f-xhalf*x*x);
return 1/x;
}
ln():
求ln函数我们可以利用泰勒级数,众所周知
但是这个函数收敛太慢了,优化一下。
众所周知, 的泰勒展开在距离1比较远不准确。
经过大量计算引入一个常数 =1.227.
#define eps 1e-30;
const double ln10=2.3025850929940456840179914547;
const double lnr=0.2002433314278771112016301167;
//用于计算ln(1+y/1-y)
double Ln(double y){
double ans=1,y2=y*y,t=y2,temp=t/3;
for(int i=3;temp>eps;temp=(t*=y2)/(i+=2))ans+=temp;
return 2*y*ans;
}
//优化计算ln(x),因为ln(1+x)泰勒展开在距离x比较远的时候不准。
double ln(double x){
int k=0,l=0;
//将x优化到(0.1,1]
for(;x>1;k++)x/=10;
for(;x<=0.1;k--)x*=10;
//将x优化到[0.9047,1.10527199)
for(;x<0.9047;l--)x*=1.2217;
//根据上面公式计算
return k*ln10+l*lnr+Ln((x-1)/(x+1));
}
double log(double x){
return ln(x)/ln2;
}
double log10(double x){
return ln(x)/ln10;
}
pow(double,double)
1.牛顿迭代。
既然上面的
函数已经实现那就可以牛顿迭代了啊。
double pow(double a,double b){
double last,now=a,lna=ln(a);
do{
last=now;
now=now-now*ln(now)+b*now*lna;
}while(abs(now-last)>eps);
return now;
}
但是这个代码速度太慢了,只能处理较小的数。
2.泰勒级数展开
double exp(double x){
double ans=1,temp=x;
for(int i=1;temp>eps;temp=temp*x/++i)ans+=temp;
return ans;
}
double pow(double a,double b){
double x=b*log(a)/log(exp(1));
return exp(x);
}
,就不一一举例了,无非都是泰勒展开和牛顿迭代而已。
变量输入及输出
c常用输入输出:
scanf("%d",&_int);
scanf("%lf",&_double);
do{
scanf("%c",&_char);//没有智能判断
}while(_char==' '||_char=='\n');
scanf("%s",_charArry);
printf("%d %f %c %s\n",_int,_double,_char,_charArry);
scanf("%*d");//只读入,不赋值
更加快速的
_char=getchar();
gets(_charArry);
putchar(_char);
puts(_charArry);
更更快速地,自己写的输入输出
/*******************************************************************/
/*******************************************************************/
template<class T>
inline int read(T &x){
char ch;
bool flag=false;
if((ch=getchar())==EOF)return -1;
for(;!isdigit(ch);ch=getchar())if(ch=='-')flag=true;
for(x=0;isdigit(ch);x=x*10+ch-'0',ch=getchar());
x=flag?-x:x;
return 1;
}
template<class T>
inline void write(T x,bool isnewline=false){
static const int maxlen=100;
static char s[maxlen];
if(x<0){putchar('-');x=-x;}
if(!x){putchar('0');return;}
int len=0;
for(;x;x/=10)s[len++]=x%10+'0';
if(isnewline)puts(s);
else for(int i=len-1;i>=0;i--)putchar(s[i]);
}
/*******************************************************************/
/*******************************************************************/
atoi(char *); 字符串转 int
atof(char *); 字符串转 double
atoll(char *); 字符串转 long long
第二章
循环
for(;;){}
do{}while();
while(){}
的计算:引申出来一个定理, 的近似计算公式:
第三章
数组和字符串
int a[maxn],b[maxn];
memcpy(b,a,sizeof(int)*K);//将a中K个数复制到b数组中
memset(a,0,sizeof a);//将a赋值为0
习题P57(本章较水,不做解析)
蛇形填数
#include<bits/stdc++.h>
using namespace std;
const int N=20;
int a[20][20];
int main(){
int n,x,y,tot;
scanf("%d",&n);
memset(a,0,sizeof a);
tot=a[x=0][y=n-1]=1;
while(tot<n*n){
while(x+1<n&&!a[x+1][y])a[++x][y]=++tot;
while(y-1>=0&&!a[x][y-1])a[x][--y]=++tot;
while(x-1>=0&&!a[x-1][y])a[--x][y]=++tot;
while(y+1<n&&!a[x][y+1])a[x][++y]=++tot;
}
for(x=0;x<n;x++){
for(y=0;y<n;y++)printf("%3d",a[x][y]);
puts("");
}
return 0;
}
UVa 272 (Tex Quotes)
https://vjudge.net/problem/UVA-272
//刘汝佳大佬的代码,膜
#include<bits/stdc++.h>
using namespace std;
int main(){
int c,q=1;
while(~(c=getchar())){
if(c=='"')printf("%s",q?"``":"''"),q=!q;
else printf("%c",c);
}
return 0;
}
UVa 1585(Score)
https://vjudge.net/problem/UVA-1585
#include<bits/stdc++.h>
using namespace std;
int main(){
int N;cin>>N;
while(N--){
string s;cin>>s;
int now=0,ans=0;
for(int i=0;i<s.length();i++){
if(s[i]=='O')now++;
else now=0;
ans+=now;
}
cout<<ans<<endl;
}
return 0;
}
UVa 1586(Molar Mass)
https://vjudge.net/problem/UVA-1586
#include<bits/stdc++.h>
using namespace std;
int main(){
int N;cin>>N;
map<char,double>mp;
mp['C']=12.01;mp['H']=1.008;mp['O']=16.00;mp['N']=14.01;
while(N--){
string s;cin>>s;
double ans=0;
for(int i=0;i<s.length();i++){
if(mp[s[i]]){
if(i+1>=s.length()||s[i+1]>'9'){
ans+=mp[s[i]];
}
else{
int kk=0;
double kkk=mp[s[i]];
while(i+1<s.length()&&!mp[s[i+1]]){
kk*=10;
kk+=s[i+1]-'0';
i++;
}
ans+=kk*kkk;
}
}
}
cout<<fixed<<setprecision(3)<<ans<<endl;
}
return 0;
}
UVa 1225(Digit Counting)
https://vjudge.net/problem/UVA-1225
#include<bits/stdc++.h>
using namespace std;
int main(){
int N,a[10];cin>>N;
while(N--){
memset(a,0,sizeof a);
int n;cin>>n;
for(int i=1;i<=n;i++){
int kk=i;
while(kk){
a[kk%10]++;
kk/=10;
}
}
for(int i=0;i<10;i++){
cout<<a[i];
if(i==9)cout<<endl;
else cout<<" ";
}
}
return 0;
}
UVa 455(Periodic Strings)
https://vjudge.net/problem/UVA-455
#include<bits/stdc++.h>
using namespace std;
int main(){
int N;cin>>N;
while(N--){
string s;cin>>s;
for(int i=1;i<=s.length();i++){
if(s.length()%i)continue;
bool flag=true;
for(int j=0;j+i<s.length();j++){
if(s[j]!=s[j+i]){flag=false;break;}
}
if(flag){
cout<<i<<endl;
if(N)cout<<endl;
break;
}
}
}
return 0;
}
UVa 227(Puzzle)
https://vjudge.net/problem/UVA-227
#include<bits/stdc++.h>
using namespace std;
#define rep(i,a,b) for(int i=a;i<=b;i++)
const int dir[4][2]={-1,0,1,0,0,1,0,-1};
const char s[]="ABRL";
char a[10][10];
int main(){
int t=0;
while(gets(a[0])){
if(a[0][0]=='Z')break;
if(t)puts("");
int m=0,n=0;
rep(i,0,4){
if(i)gets(a[i]);
rep(j,0,4){
if(a[i][j]==' '||a[i][j]==0){
a[i][j]=' ';
m=i,n=j;
}
}
}
bool flag=true;
while(true){
char c=getchar();
if(c=='0')break;
bool q=isspace(c);
rep(i,0,3){
if(!flag)break;
if(c==s[i]){
q=true;
int x=m+dir[i][0],y=n+dir[i][1];
if (x<0||x>4||y<0||y>4){
flag=false;
break;
}
a[m][n]=a[x][y];
a[x][y]=' ';
m=x,n=y;
}
}
if(!q)flag=false;
}
printf("Puzzle #%d:\n",++t);
if(flag){
rep(i,0,4){
rep(j,0,4){
if(j)printf(" ");
printf("%c",a[i][j]);
}
printf("\n");
}
}
else puts("This puzzle has no final configuration.");
getchar();
}
return 0;
}
UVa 232(Crossword Answers)
https://vjudge.net/problem/UVA-232
#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<b;i++)
typedef long long ll;
using namespace std;
struct node{
int x,y,r,c;
}st[111];
char MAP[12][12];
int n,m,Case;
int main(){
while(scanf("%d",&n),n){
scanf("%d",&m);
rep(i,0,n)scanf("%s",MAP[i]);
int num=1;
rep(i,0,n){
rep(j,0,m){
if(MAP[i][j]!='*'){
if((i-1)<0||(j-1)<0||MAP[i-1][j]=='*'||MAP[i][j-1]=='*'){
st[num].x=i;
st[num].y=j;
if((j-1)<0||MAP[i][j-1]=='*')st[num].r=1;
else st[num].r=0;
if((i-1)<0||MAP[i-1][j]=='*')st[num].c=1;
else st[num].c=0;
num++;
}
}
}
}
if(Case)puts("");
printf("puzzle #%d:\nAcross\n",++Case);
rep(i,1,num){
if(st[i].r){
printf("%3d.",i);
rep(j,st[i].y,m){
if(MAP[st[i].x][j]=='*')break;
printf("%c",MAP[st[i].x][j]);
}
printf("\n");
}
}
puts("Down");
rep(i,0,num){
if(st[i].c){
printf("%3d.",i);
rep(j,st[i].x,n){
if(MAP[j][ st[i].y ]=='*')break;
printf("%c",MAP[j][st[i].y]);
}
printf("\n");
}
}
}
return 0;
}
Uva 1368(DNA Consensus String)
https://vjudge.net/problem/UVA-1368
#include<bits/stdc++.h>
using namespace std;
string a[55],ans;
int main(){
int T;cin>>T;
while(T--){
ans="";
int m,n;cin>>m>>n;
for(int i=0;i<m;i++)cin>>a[i];
int dis=0;
for(int i=0;i<n;i++){
int A=0,T=0,G=0,C=0;
for(int j=0;j<m;j++){
if(a[j][i]=='A')A++;
if(a[j][i]=='C')C++;
if(a[j][i]=='G')G++;
if(a[j][i]=='T')T++;
}
int M=max(A,max(C,max(G,T)));
if(M==A)ans+='A',dis+=C+G+T;
else if(M==C)ans+='C',dis+=A+G+T;
else if(M==G)ans+='G',dis+=A+C+T;
else if(M==T)ans+='T',dis+=A+C+G;
}
cout<<ans<<endl<<dis<<endl;
}
return 0;
}
UVa 202(Repeating Decimals)
https://cn.vjudge.net/problem/UVA-202
有点恶心,非要这样输出干啥!
#include<bits/stdc++.h>
using namespace std;
int a[3010],b[3010],vis[3010];
int main(){
int n,m,t;
while(cin>>n>>m){
t=n;
memset(a,0,sizeof a);
memset(b,0,sizeof b);
memset(vis,0,sizeof vis);
int cnt=0;
a[cnt++]=n/m;
n=n%m;
while(!vis[n]&&n){
vis[n]=cnt;
b[cnt]=n;
a[cnt++]=10*n/m;
n=10*n%m;
}
printf("%d/%d = %d",t,m,a[0]);
printf(".");
for(int i=1;i<cnt&&i<=50;i++){
if(n&&b[i]==n)printf("(");
printf("%d",a[i]);
}
if(!n)printf("(0");
if(cnt>50)printf("...");
printf(")\n");
printf(" %d = number of digits in repeating cycle\n\n",n?cnt-vis[n]:1);
}
return 0;
}
UVa 10340(All in All)
https://vjudge.net/problem/UVA-10340
#include<bits/stdc++.h>
using namespace std;
string a,b;
int lena,lenb,cura,curb;
int main(){
while(cin>>a>>b){
lena=a.length(),lenb=b.length();
cura=curb=0;
while(cura<lena&&curb<lenb){
if(a[cura]==b[curb])cura++,curb++;
else curb++;
}
if(cura>=lena)puts("Yes");
else puts("No");
}
return 0;
}
UVa 1587(Box)
https://vjudge.net/problem/UVA-1587
#include<bits/stdc++.h>
using namespace std;
set<int>st;
struct node{
int x,y;
bool get(){if(cin>>x>>y){st.insert(x),st.insert(y);if(x<y)swap(x,y);return true;}return false;}
friend bool operator < (node A,node B){return A.x==B.x?A.y>B.y:A.x>B.x;}
friend bool operator == (node A,node B){return A.x==B.x&&A.y==B.y;}
}a[6];
int main(){
while(a[0].get()){
for(int i=1;i<6;i++)a[i].get();
if(st.size()<=3){
sort(a,a+6);
if(a[0]==a[1]&&a[2]==a[3]&&a[4]==a[5])cout<<"POSSIBLE"<<endl;
else cout<<"IMPOSSIBLE"<<endl;
}
else cout<<"IMPOSSIBLE"<<endl;
st.clear();
}
return 0;
}
UVa 1588(Kickdown)
https://vjudge.net/problem/UVA-1588
#include<bits/stdc++.h>
using namespace std;
string a,b;
int lena,lenb,MIN=0;
int main(){
while(cin>>a>>b){
lena=a.length(),lenb=b.length();
if(lena<lenb)swap(a,b),swap(lena,lenb);
MIN=lena+lenb;
for(int i=0;i<lena+lenb;i++){
bool flag=true;
if(i<lenb)
for(int j=0;j<=i;j++){
if(a[lena-1-i+j]+b[j]-'0'>'3'){flag=false;break;}
}
else if(i<lena)
for(int j=0;j<lenb;j++){
if(a[lena-1-i+j]+b[j]-'0'>'3'){flag=false;break;}
}
else
for(int j=i-lena;j<lenb;j++){
if(a[j-i+lena]+b[j]-'0'>'3'){flag=false;break;}
}
if(flag)
if(i<lenb)MIN=min(MIN,lena+lenb-1-i);
else if(i<lena)MIN=lena;
else MIN=min(MIN,i);
}
cout<<MIN<<endl;
}
return 0;
}
UVa 11809(Floating-Point Numbers)
https://vjudge.net/problem/UVA-11809
//参照网上思路,打表。
#include<bits/stdc++.h>
using namespace std;
#define eps 1e-4
#define rep(i,a,b) for(int i=a;i<=b;i++)
string in;
double M[20][40];
long long E[20][40];
int main(){
rep(i,0,9)rep(j,1,30){
double m=1-pow(2,-1-i),e=pow(2,j)-1;
double t=log10(m)+e*log10(2);
E[i][j]=t,M[i][j]=pow(10,t-E[i][j]);
}
while(cin>>in&&in!="0e0"){
for(string::iterator i=in.begin();i!=in.end();i++)if(*i=='e')*i=' ';
istringstream ss(in);
double A;int B;
ss>>A>>B;
while(A<1)A*=10,B-=1;
rep(i,0,9)rep(j,1,30){
if(B==E[i][j]&&(fabs(A-M[i][j])<eps||fabs(A/10-M[i][j])<eps)){
cout<<i<<' '<<j<<endl;
break;
}
}
}
}