使用CSS3的自定义字体美化文字

之前看到一些设计师的主题的字体很美,下载下来发现使用了css3的自定义字体,可以用来显示服务器上的字体,非常方便,学习了一下 1.首先得到字体 这个方法很多,本机的字体,一些国外的免费网站,比如这个:http://www.dafont.com,下载后的字体一般为ttf格式,ttf字体被很多浏览器支持,但是,IE不支持,为了兼容性,需要为IE单独设置字体文件,格式必须为eot,所以我们需要转换字体,使用在线工具,比如http://www.kirsle.net/wizards/ttf2eot.cgi,当然类似的网站有很多,根据个人爱好,随意。 2.添加内容 这里,我写一个简单的html文件,内容为 <body> <p class="test">bystander</p> </body> 在没有设置customFont这个类的css之前,字体就是默认的字体了。 3.设置css样式 @font-face { font-family:myFont;/*主流浏览器可用*/ src:url("PONCTUATION.ttf"); } @font-face { font-family:myFont;/*兼容IE*/ src:url("PONCTUATION.eot"); } .test { font-family:myFont; font-size:40px; } 显示效果就是这样的了…只是用来演示的一个字体。 因为浏览器是要自动下载这个字体文件的,所以对于英文字体没啥问题,英文字体一般这个字体文件在100k左右,和一张图片比起来,基本算不是问题,但是对于中文字体,包一般在10M-20M左右,这样是不现实的,我的想法是,可以自己制作字体包,这样只需要满足常用的一些汉字就行了,大大减少包的大小,然后去找了一下,发现了http://www.high-logic.com/font-editor/fontcreator.html这个软件,是可以直接编辑字体包的,也可以创建字体包,有空了用来试试.

2013-07-17 · 1 min · bystander

等物体填充问题

那天在群里,rich大牛提了一个问题,一个直径为10cm的球内最多能够填充直径为1cm的球多少个. 之前看到过一个类似的简单说明,就像是在一个盒子里装乒乓球,如果装满了,想继续装,如何办?经验告诉我们,摇一摇盒子。。这个问题看上去简单,其实是个NP难问题…于是,查找了一些资料,比较有意思,分享一下。 首先是stetson大学efriedma教授的网页,收集了各类填充(英文是packing)问题的图示,欢迎移步:packing center ,不过这里面恰好没有球体填充(SpherePacking)的问题,然后继续查找,进入了一个可以演示球体填充问题的页面:sphere packing demo 感谢网站作者Hugo Pfoertner,这里作者解出了1-72个球的问题,但是,作者说对于n>10的情况无法证明最优化.不过这个页面的演示太帅了,推荐看看。 可以鼠标拖动旋转3D视角。 然后在数学世界看到了一球体填充问题的证明结果,见:SpherePacking,当然,下面一大堆引用我都没看..看文章里的意思是说这个填充问题填充率已经被证明最大是77.9%,但是这个上限可能还能提高,因为貌似根据这个情况,rich大牛提出的这个问题应该数量在779左右..

2013-06-29 · 1 min · bystander

委托和事件示例

C#中委托和事件的例子比较多,讲得好的非常好,就不瞎凑热闹了,推荐博客园大牛的一篇: C# 中的委托和事件 ,如果你已经有了相应的基础,但没写过相关的例子,那我这里提供一个,首先看一下规范 .Net Framework的编码规范: 委托类型的名称都应该以EventHandler结束。 委托的原型定义:有一个void返回值,并接受两个输入参数:一个Object 类型,一个 EventArgs类型(或继承自EventArgs)。 事件的命名为 委托去掉 EventHandler之后剩余的部分。 继承自EventArgs的类型应该以EventArgs结尾。 然后描述一下流程: 老板监视时间变动(ComputerOffWorkTime方法),当工作时间满50后,通知员工时间到(OnNotifyOffWork方法,并传递OffWorkEventArgs参数),可以下班了,(OnNotifyOffWork方法内部调用事件NotifyOffWork),正式员工收到通知后,则下班,其他员工则清扫一下办公室 然后给出例子: using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Security.Cryptography; using System.Text; namespace DelegateAndEvent { public class Boss { //表示工作时间 private int virTime; //下班时老板说的话 public String SaidWords { get { return "Boss:时间到,下班了"; } } //委托定义 public delegate void NotifyOffWorkEventHandler(Object sender, OffWorkEventArgs e); //事件 public event NotifyOffWorkEventHandler NotifyOffWork; //事件参数 public class OffWorkEventArgs:EventArgs { public readonly int virTime; public OffWorkEventArgs(int virTime) { this.virTime = virTime; } } //触发事件 protected void OnNotifyOffWork(OffWorkEventArgs e) { if (NotifyOffWork!=null) { NotifyOffWork(this, e); } } //执行操作 public void ComputerOffWorkTime() { for (int i = 1; i <= 50; i++) { virTime = i; if (i>=50) { OffWorkEventArgs e = new OffWorkEventArgs(i); OnNotifyOffWork(e); } } } } //正式员工 public class FormalEmployee { public static void GoHome(Object sender, Boss.OffWorkEventArgs e) { Boss boss = (Boss) sender; Console.WriteLine(boss.SaidWords); Console.WriteLine(e.virTime); Console.WriteLine("FormalEmployee:准备回家"); } } //其他员工 public class OtherEmployee { public static void CleanOffice(Object sender, Boss.OffWorkEventArgs e) { Boss boss = (Boss)sender; Console.WriteLine(boss.SaidWords); Console.WriteLine(e.virTime); Console.WriteLine("OtherEmployee:准备清扫办公室"); } } public class Program { static void Main(string[] args) { Boss boss=new Boss(); //注册事件 boss.NotifyOffWork += FormalEmployee.GoHome; boss.NotifyOffWork += OtherEmployee.CleanOffice; //老板开始计时 boss.ComputerOffWorkTime(); } } }

2013-06-25 · 1 min · bystander

DMP版本修改工具(C#)

最近在使用oracle导入一个dmp文件的时候,由于不知道dmp文件是如何导出的,是使用exp还是expdp导出的,所以纠结了比较长的时间,最后想到是否可以查看dmp文件的一些辅助信息呢,于是有了这个工具。 在使用dmp导入的时候报如下错误 IMP-00010: 不是有效的导出文件,标题验证失败 IMP-00000: 未成功终止导入 据说有两个可能,1个是文件本身损坏,另一个是版本问题,多出现在高版本导出的数据向低版本导入。解决方法就是修改一下dmp文件就行了。dmp文件头部大概9个字节处标识了版本号用来头部验证。对于非常大的dmp我们不能直接用文本编辑器打开,因此找找资料,写个工具。本机一个12GB的文件已测试。 工具使用很简单,选择文件,识别出来版本,按格式改成导入端oracle的版本值,然后即可正常导入11G-10G测试成功。 下载地址:DMP版本修改工具

2013-06-11 · 1 min · bystander

阿里巴巴5月5日综合算法题详解

之前参加了阿里的笔试和电面,让后天那个敏感的日子去参加现场面,就去看了一下那天笔试的最后一道综合题,看着网上清一色最后一道题不知道从哪转的答案,不忍直视,一看代码就是错的,最直接的就是求中位数连奇偶性都不判断,直接处以2..这,另外当在无法整除的情况下,数据结果错误。 这道题的大意是:有一个淘宝商户,在某城市有n个仓库,每个仓库的储货量不同,现在要通过货物运输,将每次仓库的储货量变成一致的,n个仓库之间的运输线路围城一个圈,即1->2->3->4->…->n->1->…,货物只能通过连接的仓库运输,设计最小的运送成本(运货量*路程)达到淘宝商户的要求,并写出代码。 解题思路: 假设n个仓库的初始储货量分别为warehouse[1],warehouse[2],…,warehouse[n] 计算平均储货量 average = (warehouse[1]+warehouse[2]+...+warehouse[n])/n 就算出来了最终的结果中,每个仓库应该有的存量 首先,从仓库1向仓库n运送k; 然后,从1到n-1,依次向下运送某一特定值,使得每一个仓库的余量都为average,剩下的问题就是求总代价的最小值了。 设第0步从1仓库向n仓库(注意因为是圆圈,所以路径长度是1)运出k存量,k可以为负,如果为负数,意味着从n向1运输|k|存量,然后从循环,从(1到n-1),从i仓库向i+1仓库运输,运输的量需要保证i仓库在运输完毕后等于average 第0步(从仓库1向仓库n运送k):花费代价为 |k|, 第1步(确保仓库1的余量为average):需要花费代价为 |warehouse[1]-average-k| 也就是从1向2伙从2向1运输 3. 第2步(确保仓库2的余量为average):代价为 |warehouse[2]+warehouse[1]-average-k-average|=|warehouse[1]+warehouse[2]-2*average-k| … n-1.第n-1步:代价为 |warehouse[1]+warehouse[2]+...+warehouse[n-1]-(n-1)*average-k| 此时,仓库n剩下的货物量: (warehouse[n]+k)+warehouse[1]+warehouse[2]+...+warehouse[n-1]-(n-1)*average-k=(warehouse[1]+warehouse[2]+...+warehouse[n])-(n-1)*average=average 刚好也满足,其实这里不用推导,因为平均值是算好的,所以最胡一定是刚好完成的。 总的代价为: |k|+|warehouse[1]-average-k|+|warehouse[1]+a[2]-2*average-k|+...+|warehouse[1]+warehouse[2]+...+warehouse[n-1]-(n-1)*average-k| 不妨令sum[i] = warehouse[1]+warehouse[2]+…+warehouse[i]-i*average 则,总代价可表示为:|k|+|sum[1]-k|+|sum[2]-k|+…+|sum[n-1]-k| 这个式子可以看成在水平数轴上寻找一个点k,使得点k到点0,sum[1],sum[2],sum[3],…,sum[n-1]的距离之和最小,显然k应该取这n个数的中位数。至此问题解决。 给出详细注释代码: #include "stdafx.h" #include <iostream> #include <algorithm> #include<string> using namespace std; const int X = 100000; double sum[X],warehouse[X]; int n; double Abs(double x) { return max(x,-x); } int _tmain(int argc, _TCHAR* argv[]) { while(true) { double total = 0; double mid=0; cout<<"请输入仓库数目:"; cin>>n; //读入n个仓库的值,并计算总数 for(int i=1;i<=n;i++) { cout<<"请输入第"<<i<<"个仓库的存量:"; cin>>warehouse[i]; total += warehouse[i]; } //计算每个仓库应该最终存储的值 double average = total/n; //计算sum数组 for(int i=1;i<n;i++) sum[i] = warehouse[i]+sum[i-1]-average; //排序后打算去中位数 //sort采用半开半闭区间,所以排序为0~n-1 sort(sum,sum+n); //这个可以自己举个数字就知道了 if(n%2!=0) { mid = sum[n/2]; } else { mid=(sum[n/2]+sum[n/2-1])/2; } cout<<"应该从1开始,运输"<<mid<<"货物,然后依次保证符合条件即可"<<endl; double ans = Abs(mid); for(int i=1;i<n;i++) ans += Abs(sum[i]-mid); cout<<"总成本花费是:"<<ans<<endl; cout<<"----------------------------------------------------------------------"<<endl; } return 0; } 思路借鉴了:http://hi.baidu.com/hujunjiehit/item/54204f01931ee6c49157184c 错误之处欢迎留言指出..

2013-06-02 · 1 min · bystander

邻接表实现无向图(C++)

很早以前写的代码了,贴出来做个备份吧。用向量来存储一条邻接链表,存储可连通值。实现了判断是否连通,添加边,添加顶点的功能。 UnDirectGraph.h #pragma once #include "stdafx.h" #include <vector> using namespace std; class UnDirectGraph { private: int vCount; vector<int> *adj; public: int GetVCount(); UnDirectGraph(int vCount); void AddEdge(int v,int w); vector<int> &Vadj(int v); bool IsConnected(int v,int w); }; UnDirectGraph.cpp #pragma once #include "stdafx.h" #include "UnDirectGraph.h" using namespace std; UnDirectGraph::UnDirectGraph(int _vCount) { this->vCount=_vCount; adj=new vector<int>[vCount]; for (int i=0;i<vCount;i++) { adj[i].clear(); } } void UnDirectGraph::AddEdge(int v,int w) { adj[v].push_back(w); adj[w].push_back(v); } vector<int>& UnDirectGraph::Vadj(int v) { return adj[v]; } bool UnDirectGraph::IsConnected(int v,int w) { for (vector<int>::iterator iter=adj[v].begin();iter!=adj[v].end();iter++) { if (*iter==w) { return true; } } return false; } int UnDirectGraph::GetVCount() { return vCount; } 代码还算清晰,就不解释了,有问题留言反馈。谢谢。

2013-05-31 · 1 min · bystander

求整数1-N范围和为N的所有组合

看到的一道题,给出答案 问题:找出整数1~N范围和为N的所有集合,集合里的数不允许重复。 解答:递归吧 代码如下: #include "stdafx.h" #include <iostream> using namespace std; void PrintResult(int *log,int index) { for (int i = 0; i <index; ++i) { cout<<log[i]<<" "; } cout<<endl; } void CalCombination(int* log,int startNum,int N,int &index) { if (N==0) { PrintResult(log,index); } else { for (int i = startNum; i <= N; ++i) { log[index++]=i; CalCombination(log,i+1,N-i,index); } } index--; } int _tmain(int argc, _TCHAR* argv[]) { cout<<"请输入N:"; int N=20; cin>>N; int *log=new int[N]; int index=0; CalCombination(log,1,N,index); } 要是允许重复,也简单,将递归中的这句话改为: CalCombination(log,i,N-i,index); 同理,还可以解决类似给定一个数组,让求和为N的元素组合,只需要现将元素排个序,然后思路相同。

2013-05-27 · 1 min · bystander

武汉大学论文参考文献格式生成工具(C#)

每次写论文报告什么的,最头疼的就是参考文献的,本来打算写一个论文格式生成工具的,不过,一想起代码量,就有点吓人,所以分而治之,先写参考文献生成工具. 本工具生成的文献格式符合武汉大学本科生论文的格式要求,因此,放心使用,填写内容都是必填,页码什么的要是不知道就随便填一个..你懂的..有问题请留言反馈。 程序提供8种参考文献类型,第9种电子文献,没有实现,因为感觉在论文中参考文献要是网址的话很难看.而且用的不多..其实主要还是懒..每种文献类型需要填写的信息都不一样,8种…8种… 使用方法: 1.在界面右侧选择参考文献类型,然后填写。添加,左侧将会出现 2.如果填写错误,双击左侧条目,即可删除 3.完成后导出,即可在本目录生成docx文档 下载地址:武汉大学论文参考文献格式生成工具

2013-05-24 · 1 min · bystander

引用和指针(C++)

今天在整理收藏夹的时候,又看到了这两篇非常不错的文章,关于指针和引用的,我就不翻译了,文章很简单,不过把其中我觉得很有意思的两部分结合我的理解希望说的更清楚,假定你读这篇文章之前已经知道指针,但是不是很清楚其中的部分。 首先是关于指针的一个直观的一个认识. #include <iostream> int main() { using namespace std; // 声明并初始化指针. unsigned short int * pPointer = 0; // 定义一个unsigned short int 变量 值为35698 unsigned short int twoInt = 35698; // 定义一个unsigned short int 变量 值为 77 unsigned short int oneInt = 77; // 使用&操作符将twoInt的地址赋给指针 pPointer = &twoInt; // pPointer 现在的值就是twoInt的地址了 // 打印 cout << "pPointer的内存地址:\t\t" << &pPointer << endl; cout << "oneInt的内存地址:\t" << &oneInt << "\t整数值:\t" << oneInt << endl; cout << "twoInt的内存地址:\t" << &twoInt << "\t整数值:\t" << twoInt << endl; cout << "pPointer所指向的地址(也就是pPoint的值):\t" << pPointer << "\t整数值:\t" << *pPointer << endl; return 0; } 上面这段代码,声明了一个指针,和两个整数,指针指向第一个整数,然后输出结果(每个人的输出结果不一样)是: pPointer的内存地址: 0xbff43314 oneInt的内存地址: 0xbff43318 整数值: 77 twoInt的内存地址: 0xbff4331a 整数值: 35698 pPointer所指向的地址(也就是pPoint的值): 0xbff4331a 整数值: 35698 这张图是这几个变量的内存分布图,上面一排是内存地址编号,正对我们的是该处的值 指针pPointer这个变量从最左边0xbff43314这个内存位置开始,占用了四个字节,这个一个指针占四个字节,大家都知道的,这个变量的值是一个地址,也就是他的指向地址。 pPointer 所指向的地址呢,是一个short int 类型的值所在的位置,在这里就是我们的twoint,twoint在内存中呢,是从0xbff4331a开始的,也就是说,我们的pPointer指向了twoint所在的地址, 注意,看一下左边四个方块前面的二进制数,转换成16进制就是0xbff4331a了 因此,取指针所指向的值就是35698了。指针本身的值则是0xbff4331a,指针所在的位置是0xbff43314。 参考文章:C++ : Understanding pointers 另一个呢是关于引用的实现原理 大家都知道,引用就是别名,比如下面这段代码 #include <iostream> using namespace std; int main() { int number = 88; // 定义一个int变量 int & refNumber = number; // 声明并初始化一个引用 // 现在他们都表示了同一个值 cout << number << endl; // 打印number的值 (88) cout << refNumber << endl; // 打印引用的值 (88) refNumber = 99; // 给refNumber重新赋一个值 cout << refNumber << endl; cout << number << endl; // number的值也就变成了 (99) number = 55; // 重新给number赋一个值 cout << number << endl; cout << refNumber << endl; // refNumber也就变成了(55) } 输出结果肯定一目了然,其中的原理想过没 ...

2013-05-22 · 1 min · bystander

倒水问题求解(C++)

明天要去参加微软面试,不求顺利,但求体验。 这个题目答题的意思是: 给你一个容量为A升的桶和一个容量为B升的桶,水不限使用,要求精确得到Q升水.请说明步骤 当数字比较小的时候,我们可以通过大脑穷举来得到结果,但这里有两个问题,当数字很大的时候怎么解?题目给定的数据是否有解? 首先判断是否有解? 题目可以理解为,x为用A的次数,y为用B的次数,Q为目标值 Q = A * x + B * y Q =目标值. Q必须是 Gcd(A,B)(也就是A,B的最大公约数)的倍数,否则无解,如果 Gcd(A,B) == 1, 任何Q都是可解的 最简单的方法就是把A的水不断的向B中倒(B向A中倒也行),知道得到最终结果,如果桶满了,就清空该桶.举个例子 A = 3, B = 4 并且 Q = 2 重复得从 A->B A B 0 0 4 0 1 3 1 0 0 1 4 1 2 3 <-A桶中得到2了 试试从 B->A A B 0 0 0 3 3 0 3 3 4 2 <- B中也得到了2 但是注意,从 B->A 比从 A->B快哦 然后我贴出代码 #include "stdafx.h" #include <iostream> #include <vector> #include<string> using namespace std; //热门智力题 - 打水问题 //基本思想:用A桶容量的倍数对B桶的容量进行取余。 //指导方针:不断用A桶装水倒入B桶,B桶满了立即清空 //每次判断下二个桶中水的容量是否等于指定容量。 const string OPERATOR_NAME[7] = { "装满A桶", "装满B桶", "将A桶清空", "将B桶清空", "A桶中水倒入B桶", "B桶中水倒入A桶", "成功得到结果" }; int max(int a,int b) { return a>b?a:b; } int gcd(int m,int n) { int temp,p,r; //n存放最小数,m存放最大数 if(n>m){ temp = n; n = m; m = temp; } p=n*m;//先取得两个数的积 while(n!=0){ r=m%n; m=n; n=r; } return m; } int _tmain(int argc, _TCHAR* argv[]) { int a_capacity, b_capacity, goal_capacity; vector<string> record; //记录操作过程 int a_water, b_water; cout<<"请输入A桶容量,B桶容量,目标容量Q:"; cin>>a_capacity>>b_capacity>>goal_capacity; a_water = b_water = 0; //A桶,B桶中有多少升水 //判断是否一定可解 if (a_capacity<=0 || b_capacity<=0 || goal_capacity<=0) { cout<<"请保证所以容量大于0"<<endl; return -1; } if (goal_capacity>max(a_capacity,b_capacity)) { cout<<"要量出的容量应该小于其中桶容量"<<endl; return -2; } //如果可解则解之 if(goal_capacity%gcd(a_capacity,b_capacity)==0) { //存放临时的字符串构造 char szTemp[30]; while (true) { if (a_water == 0)//A桶没水,就装满水 { a_water = a_capacity; sprintf(szTemp, " A:%d B:%d", a_water, b_water); record.push_back(OPERATOR_NAME[0] + szTemp);//先填满 A桶 } else { //如果A桶的水比(B桶容量-B桶的水)要多,也就是多于没装满的B桶空出来的部分,A桶会剩下 if (a_water > b_capacity - b_water) { //A桶向B桶倒水直到B桶满,此时A桶的水==A桶的水+B桶的水-B桶容量 a_water = a_water + b_water- b_capacity; b_water = b_capacity; //B桶的水装满了 sprintf(szTemp, " A:%d B:%d", a_water, b_water); record.push_back(OPERATOR_NAME[4] + szTemp);//A->B if (a_water == goal_capacity) break; b_water = 0; //将B桶清空 sprintf(szTemp, " A:%d B:%d", a_water, b_water); record.push_back(OPERATOR_NAME[3] + szTemp); } else { //A桶小于装满B桶需要的水,此时B桶的水==A桶的水+B桶的水 b_water += a_water; a_water = 0; sprintf(szTemp, " A:%d B:%d", a_water, b_water); record.push_back(OPERATOR_NAME[4] + szTemp);//A->B if (b_water == goal_capacity) break; } } } record.push_back(OPERATOR_NAME[6]); //break出来说明成功了 cout<<"\n---------------------------------------------------"<<endl; cout<<"以下下是一种方案"<<endl; vector<string>::iterator pos; for (pos = record.begin(); pos != record.end(); pos++) cout<<*pos<<endl; cout<<"---------------------------------------------------"<<endl; } else { cout<<"此情况下无解"<<endl; } return 0; } 运行结果如下: ...

2013-05-15 · 2 min · bystander