|
思路:先求第一个的天数,然后用这个天数求第二个的表示方式,个人觉得不是水题
#include<stdio.h> #include<string.h> char hm[19][7]={"pop","no","zip","zotz","tzec","xul","yoxkin","mol","chen","yax", "zac","ceh","mac","kankin","muan","pax","koyab","cumhu","uayet"}; char tm[20][9]={"imix","ik","akbal","kan","chicchan","cimi","manik","lamat","muluk","ok", "chuen","eb","ben","ix","mem","cib","caban","eznab","canac","ahau"}; int main() { int i,m,n,day,year; char month[9]; scanf("%d",&n); printf("%d\n",n); while (n--) { scanf("%d.%s%d",&day,month,&year); for(i=0; i<19; i++) if(strcmp(hm[i],month) == 0) { m=365*year+20*i+day; break; } printf("%d %s %d\n",m%260%13+1,tm[m%20],m/260); } return 0; }
此程序耗费我尽3个小时之久,原因是做题前的规划没做好,一直没有想到整体排序的好办法,最后还是用了注意匹配的方法才解决了问题,我不知道为什么用冒泡不行,第一个字符串总是乱码。我觉得整体思路还是比较清晰的,只是方法可能有点傻,效率还行。 C 编译器 : 172K 0MS
#include <stdio.h> #include <string.h>
typedef struct DNA { char str[50]; // 存储字符串 int count[2]; // [0] [1]都存放串的逆序数 }DNA; // [1]中作为参考,用来和排序后的[0]匹配
int main() { int i=0,j,k=0,n,m,temp; DNA or[100]; scanf("%d%d",&n,&m); while (k<m) //获得数据并求各自逆序数 { scanf("%s",&or[k].str); or[k].count[0]=0; // 此步不能忘 for (i=0; i<n; i++) for (j=i+1; j<n; j++) if (or[k].str[i] > or[k].str[j]) or[k].count[0]++; k++; } for (i=0; i<m; i++) or[i].count[1]=or[i].count[0]; // 原逆序数存放顺序
for (i=1; i<m; i++) // 对于各组串的逆序数进行排序,count[0]内容已打乱 { k=i-1; for (j=i; j<m; j++) if (or[j].count[0] < or[k].count[0]) k=j; temp=or[i-1].count[0]; or[i-1].count[0]=or[k].count[0]; or[k].count[0]=temp; } // 这是典型的选择排序,只是对[0]单元的处理,稳定与否没关系
for (i=0; i<m; i++) for (j=0; j<m; j++) if (or[i].count[0] == or[j].count[1]) // [0] 和 [1] 中逐一相比较 { or[j].count[1]=-1; // 此步是相等时顺序不变的保证,相当于做了访问标记! printf("%s\n",or[j].str); }
return 0; }
典型的 阅读理解题 , 读懂意思基本上思路就出来了,恰巧又是一道中文题,这里用枚举,其他不解释。
#include <stdio.h> int main() { int i,a,b,c,d,days=0; while(1) { days++; scanf("%d%d%d%d",&a,&b,&c,&d); if (a+b+c+d == -4) break; for (i=d+1; ; i++) // pay attention: from d+1 { if ((i-a)%23==0) if ((i-b)%28==0) if ((i-c)%33==0) { printf("Case %d: the next triple peak occurs in %ld days.\n",days,i-d); break; } } } return 0; }
Description
Fred Mapper is considering purchasing some land in Louisiana to build his house on. In the process of investigating the land, he learned that the state of Louisiana is actually shrinking by 50 square miles each year, due to erosion caused by the Mississippi River. Since Fred is hoping to live in this house the rest of his life, he needs to know if his land is going to be lost to erosion. After doing more research, Fred has learned that the land that is being lost forms a semicircle. This semicircle is part of a circle centered at (0,0), with the line that bisects the circle being the X axis. Locations below the X axis are in the water. The semicircle has an area of 0 at the beginning of year 1. (Semicircle illustrated in the Figure.)
Input
The first line of input will be a positive integer indicating how many data sets will be included (N). Each of the next N lines will contain the X and Y Cartesian coordinates of the land Fred is considering. These will be floating point numbers measured in miles. The Y coordinate will be non-negative. (0,0) will not be given.
Output
For each data set, a single line of output should appear. This line should take the form of: “Property N: This property will begin eroding in year Z.” Where N is the data set (counting from 1), and Z is the first year (start from 1) this property will be within the semicircle AT THE END OF YEAR Z. Z must be an integer. After the last data set, this should print out “END OF OUTPUT.”
把题意弄明白,就知道这道题是水题了,由坐标 (0,0) 开始,以半圆为形状每年侵蚀50 平方 miles ,问你从 (0,0) 开始到 (x,y) 结束需要多长时间,水题不需要太关注效率,所以变量定义上没有深究,其他不解释。
编译器 C + + : #include <iostream> using namespace std; #define PI 3.1415926 int main() { int n,i=0,year; double x,y,area; cin>>n; while (i<n) { cin>>x>>y; area = 0.5 * PI * (x*x+y*y); // semicircle area equation year = area/50; printf("Property %d: This property will begin eroding in year %d.\n",i+1,year+1); i++; } printf("END OF OUTPUT.\n"); return 0; }
正宗水题,就是输入12个浮点数,让你求平均值,不解释。
#include<stdio.h>
int main()
{
float i=0,m,s=0;
for(;i<12;i++)
{
scanf("%f",&m);
s+=m;
}
printf("$%.2f\n",s/12);
return 0;
}
正宗水题,题目把最主要的公式都给你了,只要计算1/2+1/3+1/4+......+1/(n+1) >= x中最小的n值即可,我这里的cards用的是整形,注意底下一定要乘以1.0,否则会让你调试的生不如死的,要不你就让cards 是浮点型,其他的不解释。 #include<stdio.h>
int main() { int cards; float length,c; for(scanf("%f",&c); c!=0.0; scanf("%f",&c)) { for(cards=0,length=0; length<c; ) { cards++; length+=1/(cards*1.0+1); } printf("%d card(s)\n",cards); } return 0; } //180K 0MS
事先申明,该程序虽然AC,但是效率极其低下,低下到让人发指的程度,我也不知道为什么。估计是用了STL的原因,具体我也说不清楚。其实思路不难,就是将字符转化成对应数字,然后将结果存放在一个整型向量中,接收字符串用的是字符串向量,处理的时候跟一般的字符串处理时一模一样的。处理结束之后要进行字典排序,显然要用排序函数,可以用冒泡,选择,快排,甚至是Hash,但是据说STL的sort 效率比快排还要快。源程序后附加了MSDN上的一些简单解释。没有翻译!
Description
Businesses like to have memorable telephone numbers. One way to make a telephone number memorable is to have it spell a memorable word or phrase. For example, you can call the University of Waterloo by dialing the memorable TUT-GLOP. Sometimes only part of the number is used to spell a word. When you get back to your hotel tonight you can order a pizza from Gino's by dialing 310-GINO. Another way to make a telephone number memorable is to group the digits in a memorable way. You could order your pizza from Pizza Hut by calling their ``three tens'' number 3-10-10-10.
The standard form of a telephone number is seven decimal digits with a hyphen between the third and fourth digits (e.g. 888-1200). The keypad of a phone supplies the mapping of letters to numbers, as follows:
A, B, and C map to 2 D, E, and F map to 3 G, H, and I map to 4 J, K, and L map to 5 M, N, and O map to 6 P, R, and S map to 7 T, U, and V map to 8 W, X, and Y map to 9
There is no mapping for Q or Z. Hyphens are not dialed, and can be added and removed as necessary. The standard form of TUT-GLOP is 888-4567, the standard form of 310-GINO is 310-4466, and the standard form of 3-10-10-10 is 310-1010.
Two telephone numbers are equivalent if they have the same standard form. (They dial the same number.)
Your company is compiling a directory of telephone numbers from local businesses. As part of the quality control process you want to check that no two (or more) businesses in the directory have the same telephone number.
Input
The input will consist of one case. The first line of the input specifies the number of telephone numbers in the directory (up to 100,000) as a positive integer alone on the line. The remaining lines list the telephone numbers in the directory, with each number alone on a line. Each telephone number consists of a string composed of decimal digits, uppercase letters (excluding Q and Z) and hyphens. Exactly seven of the characters in the string will be digits or letters.
Output
Generate a line of output for each telephone number that appears more than once in any form. The line should give the telephone number in standard form, followed by a space, followed by the number of times the telephone number appears in the directory. Arrange the output lines by telephone number in ascending lexicographical order. If there are no duplicates in the input print the line: No duplicates.
C++ 编译器:
#include <iostream> #include <string> #include <vector> #include <algorithm> // STL sort function using namespace std;
char map[] = "2223334445556667#77888999#"; //ABCDEFGHIJKLMNOPQRSTUVWXYZ void visited(char &ch) // visit and format strings { if (ch >= 'A' && ch <= 'Z') ch=map[ch-'A']; // ch equals to its real number }
int main() { int N,i=0,j,flag=0; string s; vector<string> stored(100000); // be visited & stored (up to 100,000) cin>>N; vector<int> counter(N,1); // stored times for (; i<N; i++) { cin>>s; for (j=0; j<s.length(); j++) // MSDN { visited(s[j]); if (s[j]!='-') { stored[i] += s[j]; if (stored[i].length()==3) stored[i] += '-'; // 487 -[3] 3279 } } } sort(stored.begin(),stored.begin()+N); // Quicker than QuickSort! // should not used stored.end() ! i=0; j=1; while (i<N) { while(stored[i] == stored[j]) { counter[i]++; j++; flag=1; } i=j; j++; } if (flag) for (i=0; i<N; i++) { if (counter[i]>1) cout<<stored[i]<<" "<<counter[i]<<endl; } // must have { } else cout<<"No duplicates."<<endl; return 0; }
Sort : Arranges the elements in a specified range into a nondescending order or according to an ordering criterion specified by a binary predicate.
template<class RandomAccessIterator> void sort( RandomAccessIterator _First, RandomAccessIterator _Last );
分类开篇语: 第一个程序搞了好几天,发现了很多问题。POJ不保证按顺序做且更新速度肯定不会很快。有些题自己做不出来借鉴别人的会注明出处。很多算法都需要从网上找,第一题的大浮点数相乘的核心算法就是这样找来的。我心里明白,虽然AC了,但是边缘数据处理的很粗糙,我自己都发现几个bug了,但是依然AC了。
本题主要注意将字符串转化为实际的数字然后借鉴数制的思想来进行大数相乘。
Description
Problems involving the computation of exact values of very large magnitude and precision are common. For example, the computation of the national debt is a taxing experience for many computer systems.
This problem requires that you write a program to compute the exact value of Rn where R is a real number ( 0.0 < R < 99.999 ) and n is an integer such that 0 < n <= 25.
Input
The input will consist of a set of pairs of values for R and n. The R value will occupy columns 1 through 6, and the n value will be in columns 8 and 9.
Output
The output will consist of one line for each line of input giving the exact value of R^n. Leading zeros should be suppressed in the output. Insignificant trailing zeros must not be printed. Don't print the decimal point if the result is an integer.
Sample Input
95.123 12
0.4321 20
5.1234 15
6.7592 9
98.999 10
1.0100 12
Sample Output
548815620517731830194541.899025343415715973535967221869852721
.00000005148554641076956121994511276767154838481760200726351203835429763013462401
43992025569.928573701266488041146654993318703707511666295476720493953024
29448126.764121021618164430206909037173276672
90429072743629540498.107596019456651774561044010001
1.126825030131969720661201
编译器C++ 源码:
#include <iostream> #include <string> using namespace std; #define MAX 255 int getnum(string s,int *c) // get real number of R { int i=0,j=0,t[MAX]; memset(t,0,sizeof(int)*MAX); // a stores 0 while (i < 6) // R value 1 through 6 { if (s[i] != '.') { t[j]=s[i]-'0'; j++; } i++; } // a`s length = 5 for (j=0; j<5; j++) c[j]=t[4-j]; // c stores in order from a for (i=0; s[i] != '.'; i++); // find decimal point
return (5-i); // the position of . point } void multi(int *a,int *b) // big-multiplication { int i=0,j,r=0,t[MAX]; memset(t,0,sizeof(int)*MAX); // t stores 0 for (; i<5; i++) for (j=0; j<255; j++) t[i+j] += a[i]*b[j]; // core algorithms! for (i=0; i<255; i++) { b[i]=(r+t[i])%10; // r always stores remainder r=(r+t[i])/10; // b stores the result } } // basic algorithms of b-m
int main() { int i,j,d_pos,n,a[MAX],b[MAX]; string s;
while (cin>>s>>n) { memset(b,0,sizeof(int)*MAX); memset(a,0,sizeof(int)*MAX); d_pos=getnum(s,a); getnum(s,b); for (i=0; i<n-1; i++) multi(a,b); // a is a loop invariant for (i=254; !b[i]; i--); //find last non-zero for (j=0; !b[j]; j++); // find first non-zero for (; i >= n*d_pos; i--) // loop n times cout<<b[i]; if (n*d_pos >= j+1) cout<<"."; //pay attention for (i=n*d_pos-1; i>=j; i--) cout<<b[i]; //from back formating output cout<<endl; } return 0; }
1. 计算复杂性 O 这是描述一种算法需要多少 Running time 的度量。(也有空间复杂性,但因为它们能相互转换,所以通常我们就说时间复杂性。对于大小为 n 的输入,我们用含 n 的简化式子来表达。(所谓简化式子,就是忽略系数、常数,仅保留最“大”的那部分)。 比如找出 n 个数中最大的一个,很简单,就是把第一个数和第二个比,其中大的那个再和第三个比,依次类推,总共要比 n-1 次,我们记作 O(n) (对于 n 可以是很大很大的情况下,-1可以忽略不计了)。 再比如从小到大排好的 n 个数,从中找出等于 x 的那个。一种方法是按着顺序从头到尾一个个找,最好情况是第一个就是 x,最坏情况是比较了 n 次直最后一个,因此最坏情况下的计算复杂度也是 O(n)。还有一种方法:先取中间那个数和 x 比较,如偏大则在前一半数中找,如偏小则在后一半数中找,每次都是取中间的那个数进行比较,则最坏情况是 lg(n)/lg2。忽略系数lg2,算法复杂度是O(lgn)。 2. 计算复杂性的排序 根据含 n 的表达式随 n 增大的增长速度,可以将它们排序:1 < lg(n) < n < nlg(n) < n^2 < ... < n^k (k是常数)< ... < 2^n (不用死记,想象它们的函数曲线,一看便明)。最后这个 2 的n 次方就是级数增长了,读过棋盘上放麦粒故事的人都知道这个增长速度有多快。而之前的那些都是 n 的多项式时间的复杂度。为什么我们在这里忽略所有的系数、常数,例如 2*n^3+9*n^2 可以被简化为 n^3?老师上课也没有说原因,所以我也不知道。但是如果对对 (2*n^3+9*n^2)/(n^3) 求导,结果是0,仔细想想,我也没有想出所以然来。 3. P 问题
对一个问题,凡是能找到计算复杂度可以表示为多项式的确定算法,这个问题就属于 P (polynomial) 问题。 4. NP 问题 NP 中的 N 是指非确定的(non-deterministic)算法,这是这样一种算法:
(1)猜一个答案。(2)验证这个答案是否正确。(3)只要存在某次验证,答案是正确的,则该算法得解。 NP (non-deterministic polynomial)问题就是指,用这样的非确定的算法,验证步骤(2)有多项式时间的计算复杂度的算法。 5. 问题的归约 想象一下函数的映射是怎么一回事吧。这个概念需要弄懂。 大致就是这样:找从问题1的所有输入到问题2的所有输入的对应,如果相应的,也能有问题2的所有输出到问题1的所有输出的对应,则若我们找到了问题2的解法,就能通过输入、输出的对应关系,得到问题1的解法。由此我们说问题1可归约到问题2。
再给一个我找到的高端解释:
问题归约是人求解问题常用的策略,其把复杂的问题变换为若干需要同时处理的较为简单的子问题后再加以分别求解。只有当这些子问题全部解决时,问题才算解决,问题的解答就由子问题的解答联合构成。问题归约可以递归地进行,直到把问题变换为本原问题的集合。所谓本原问题就是不可或不需再通过变换化简的"原子"问题,本原问题的解可以直接得到或通过一个"黑箱"操作得到。 6. NP-Hard 有这样一种问题,所有 NP 问题都可以归约到这种问题,我们称之为 NP-hard 问题。 7. NP完全问题 (NP-Complete) 如果一个问题既是 NP 问题又是 NP-Hard 问题,则它是 NP-Complete 问题。可满足性问题就是一个 NP 完全问题,此外著名的给图染色、哈密尔顿环、背包、货郎问题都是 NP 完全问题。
解压缩版本的Eclipse打开时遇到此类问题:
解决方法:
打开安装目录下的eclipse.config(或eclipse.ini)配置文件,大致的内容如下,
-startup
plugins/org.eclipse.equinox.launcher_1.0.200.v20090520.jar
--launcher.library
plugins/org.eclipse.equinox.launcher.win32.win32.x86_1.0.200.v20090519
-product
org.eclipse.epp.package.jee.product
--launcher.XXMaxPermSize
256M
-showsplash
org.eclipse.platform
--launcher.XXMaxPermSize
256m
-vmargs
-Dosgi.requiredJavaVersion=1.5
-Xms40m
-Xmx512m
其中的“Xmx512m” 改成“Xmx256m”
|