程序设计能力实训 资料准备
注意:C++限定。
高精度
//加法(非负)
inline string add(string s1, string s2)
{
string s;
int len1 = s1.size(), len2 = s2.size();
if (len1 < len2)
for (int i = 1; i <= len2-len1; ++i)
s1 = "0" + s1;
else
for (int i = 1; i <= len1-len2; ++i)
s2 = "0" + s2;
len1 = s1.size();
int plus = 0, tmp;
for (int i = len1-1; i >= 0; --i)
{
tmp = s1[i]-'0' + s2[i]-'0' + plus;
plus = tmp / 10;
tmp %= 10;
s = char(tmp+'0') + s;
}
if (plus) s = char(plus+'0') + s;
return s;
}
//减法
inline int cmp(const string& s1, const string& s2)
{
if (s1.size() > s2.size()) return 1;
else if (s1.size() < s2.size()) return -1;
else return s1.compare(s2);
}
inline string subtract(string s1, string s2)
{
string s;
if (!cmp(s1, s2)) return "0";
if (cmp(s1, s2) < 0) {putchar('-'); swap(s1, s2);}
int tmp = s1.size() - s2.size(), minus = 0;
for (int i = s2.size()-1; i >= 0; --i)
{
if (s1[i+tmp] < s2[i]+minus)
{
s = char(s1[i+tmp] - s2[i] - minus + '0'+10) + s;
minus = 1;
} else
{
s = char(s1[i+tmp] - s2[i] - minus + '0') + s;
minus = 0;
}
}
for (int i = tmp-1; i >= 0; --i)
{
if (s1[i] - minus >= '0')
{
s = char(s1[i]-minus) + s;
minus = 0;
} else
{
s = char(s1[i] - minus + 10) + s;
minus = 1;
}
}
s.erase(0, s.find_first_not_of('0'));
return s;
}
//乘法(非负)(需要前面的add)
inline string mul(string s1, string s2)
{
string s, stmp;
int len1 = s1.size(), len2 = s2.size();
for (int i = len2-1; i >= 0; --i)
{
stmp = "";
int tmp = s2[i]-'0', plus = 0, t = 0;
if (tmp)
{
for (int j = 1; j <= len2-i-1; ++j)
stmp += "0";
for (int j = len1-1; j >= 0; --j)
{
t = (tmp*(s1[j]-'0') + plus) % 10;
plus = (tmp*(s1[j]-'0') + plus) / 10;
stmp = char(t+'0') + stmp;
}
if (plus) stmp = char(plus+'0') + stmp;
}
s = add(s, stmp);
}
s.erase(0, s.find_first_not_of('0'));
if (s.empty()) s = "0";
return s;
}
//阶乘
void fact(int n)
{
int result[10005];
memset(result, 0, sizeof(result));
result[0] = 1;
for (int i = 2; i <= n; ++i)
{
int left = 0;
for (int j = 0; j < 10000; ++j)
{
result[j] = left + result[j] * i;
left = result[j] / 10;
result[j] %= 10;
}
}
int k = 9999;
while (!result[k])
k--;
for (int i = k; i >= 0; --i)
printf("%d", result[i]);
printf("\n");
}
除法比较特殊,单独拿出来(非负,需要前面的subtract和mul,除数不能为0):
inline void div(string s1, string s2, string& quot, string& rem)
{
quot = rem = "";
if (s1 == "0")
{
quot = rem = "0";
return;
}
int comp = cmp(s1, s2);
if (comp < 0)
{
quot = "0";
rem = s1;
return;
}else if (!comp)
{
quot = "1";
rem = "0";
return;
} else
{
int len1 = s1.size(), len2 = s2.size();
string stmp;
stmp.append(s1, 0, len2-1);
for (int i = len2-1; i < len1; ++i)
{
stmp += s1[i];
stmp.erase(0, stmp.find_first_not_of('0'));
if (stmp.empty()) stmp = "0";
for (char c = '9' ; c >= '0'; --c)
{
string s, tmp;
s += c;
tmp = mul(s2, s);
if (cmp(tmp, stmp) <= 0)
{
quot += c;
stmp = subtract(stmp, tmp);
break;
}
}
}
rem = stmp;
}
quot.erase(0, quot.find_first_not_of('0'));
if (quot.empty()) quot = "0";
}
大整数类
struct BigInteger
{
static const int BASE = 1e8;
static const int WIDTH = 8;
vector s;
BigInteger(long long num = 0) { *this = num; }
BigInteger operator = (long long);
BigInteger operator = (const string&);
BigInteger operator + (const BigInteger&) const;
BigInteger operator - (const BigInteger&) const;
BigInteger operator * (const BigInteger&) const;
BigInteger operator / (const BigInteger&) const;
BigInteger operator += (const BigInteger&);
BigInteger operator -= (const BigInteger&);
BigInteger operator *= (const BigInteger&);
BigInteger operator /= (const BigInteger&);
bool operator < (const BigInteger&) const;
bool operator > (const BigInteger&) const;
bool operator <= (const BigInteger&) const;
bool operator >= (const BigInteger&) const;
bool operator != (const BigInteger&) const;
bool operator == (const BigInteger&) const;
};
BigInteger BigInteger::operator = (long long num) //重载=运算符(数字赋值)
{
s.clear();
do
{
s.push_back(num%BASE);
num /= BASE;
}while (num > 0);
return *this;
}
BigInteger BigInteger::operator = (const string& str) //重载=运算符(字符串赋值)
{
s.clear();
int x, len = (str.length() - 1) / WIDTH + 1;
for (int i = 0; i < len; ++i)
{
int end = str.length() - i * WIDTH;
int start = max(0, end-WIDTH);
sscanf(str.substr(start, end-start).c_str(), "%d", &x);
s.push_back(x);
}
return *this;
}
BigInteger BigInteger::operator + (const BigInteger& b) const //重载+运算符
{
BigInteger c;
c.s.clear();
for (int i = 0, g = 0; ; ++i)
{
if (!g && i >= s.size() && i >= b.s.size())
break;
int x = g;
if (i < s.size())
x += s[i];
if (i < b.s.size())
x += b.s[i];
c.s.push_back(x%BASE);
g = x / BASE;
}
return c;
}
BigInteger BigInteger::operator += (const BigInteger& b) //重载+=运算符
{
*this = *this + b;
return *this;
}
bool BigInteger::operator < (const BigInteger& b) const //重载<运算符
{
if (s.size() != b.s.size())
return s.size() < b.s.size();
for (int i = s.size()-1; i >= 0; --i)
if (s[i] != b.s[i])
return s[i] < b.s[i];
return false;
}
bool BigInteger::operator > (const BigInteger& b) const //重载>运算符
{
return b < *this;
}
bool BigInteger::operator <= (const BigInteger& b) const //重载<=运算符
{
return !(b < *this);
}
bool BigInteger::operator >= (const BigInteger& b) const //重载>=运算符
{
return !(*this < b);
}
bool BigInteger::operator != (const BigInteger& b) const //重载!=运算符
{
return b < *this || *this < b;
}
bool BigInteger::operator == (const BigInteger& b) const //重载==运算符
{
return !(b < *this) || !(*this < b);
}
ostream& operator << (ostream& out, const BigInteger& x) //重载<<运算符
{
out << x.s.back();
for (int i = x.s.size()-2; i >= 0; --i)
{
char buf[20];
sprintf(buf, "%08d", x.s[i]);
for (int j = 0; j < strlen(buf); ++j)
out << buf[j];
}
return out;
}
istream& operator >> (istream& in, BigInteger& x) //重载>>运算符
{
string s;
if (!(in >> s))
return in;
x = s;
return in;
}
快速幂取模
typedef long long ll;
ll pow_mod(int a, int b, int p)
{
ll ret = 1;
while (b)
{
if (b&1) ret = (ret * a) % p;
a = (a * a) % p;
b >>= 1;
}
return ret;
}
扩展欧几里得
int extgcd(int a, int b, int &x, int &y)
{
if (!b)
{
x = 1; y = 0;
return a;
}
int d = extgcd(b, a % b, x, y);
int t = x;
x = y;
y = t - a / b * y;
return d;
}
素数相关
//欧拉筛
const int maxn = 1e7+5;
bool np[maxn]{true,true};
vector<int> prime;
int main()
{
int n, m, x;
cin >> n >> m;
for (int i = 2; i <= n; ++i)
{
if (!np[i]) prime.push_back(i);
for (int j = 0; j < prime.size() && i*prime[j] <= n; ++j)
{
np[i*prime[j]] = true;
if (i % prime[j] == 0) break;
}
}
for (int i = 1; i <= m; ++i)
{
scanf("%d", &x);
printf("%s\n", np[x] ? "No" : "Yes");
}
return 0;
}
//埃氏筛
const int maxn = 1e6+5;
bool np[maxn]{true, true};
void init()
{
for (int i = 2; i < maxn; i++)
if (!np[i])
{
if (i > maxn/i) continue; //或用ll省去这一步
for (int j = i*i; j < maxn; j += i)
np[j] = true;
}
}
//单独判断 O(sqrt(n))
typedef long long ll;
inline bool isprime(ll m)
{
for (ll i = 2; i * i <= m; ++i)
if (!(m % i)) return false;
return true;
}
//区间筛
typedef long long ll;
const int maxn = 1e6+5;
ll a, b;
bool isp[maxn], ispsmall[maxn];
void seg_sieve()
{
for (ll i = 2; i*i <= b; ++i) ispsmall[i] = true;
for (ll i = 0; i <= b-a; ++i) isp[i] = true;
for (ll i = 2; i*i <= b; ++i)
if (ispsmall[i])
{
for (ll j = (i<<1); j*j <= b; j += i) ispsmall[j] = false;
for (ll j = max(2LL, (a+i-1)/i) * i; j <= b; j += i) isp[j-a] = false;
}
if (a <= 1) isp[1-a] = false;
bool flag = false;
for (ll i = 0; i <= b-a; ++i)
if (isp[i])
{
if (flag) printf(" %lld", i+a);
else flag = true, printf("%lld", i+a);
}
flag ? puts("") : puts("no prime number.");
}
约瑟夫
int n, m;
vector<int> v;
int main()
{
cin >> n >> m;
if (!n && !m) return 0;
for (int i = 1; i <= n; ++i)
v.push_back(i);
int kill = 0;
while (v.size() > 1)
{
kill = (kill+m-1) % v.size();
printf("%d ", v[kill]);
v.erase(v.begin()+kill);
}
printf("%d\n", v[0]);
return 0;
}
组合数计算
typedef long long ll;
ll C[41][41];
void calc()
{
C[1][0] = C[1][1] = 1;
for(int i = 2; i <= 40; ++i)
{
C[i][0] = 1;
for(int j = 1; j <= i; ++j)
C[i][j] = C[i-1][j] + C[i-1][j-1];
}
}
LIS(nlogn)
fill(f, f+n, INF);
for (int i = 0; i < n; ++i)
*lower_bound(f, f+n, a[i]) = a[i];
printf("%d\n", lower_bound(f, f+n, INF) - f);
闰年判断
bool is_leap(int n)
{
return ((n % 4 == 0 && n % 100)|| n % 400 == 0) ? 1 : 0;
}
输出给定日期是星期几
int main()
{
int y, m, d;
scanf("%d-%d-%d", &y, &m, &d);
if (m == 1 || m == 2){
--y;
m += 12;
}
int c = y / 100;
int yy = y - c * 100;
int day = yy + yy / 4 + c / 4 - 2 * c + 13 * (m + 1) / 5 + d - 1;
if (y <= 1582 && m <= 10 && d <= 4) day += 3;
while (day < 0) day += 7;
day %= 7;
switch(day){
case 1: printf("Monday\n");break;
case 2: printf("Tuesday\n");break;
case 3: printf("Wednesday\n");break;
case 4: printf("Thursday\n");break;
case 5: printf("Friday\n");break;
case 6: printf("Saturday\n");break;
default: printf("Sunday\n");
}
return 0;
}
一些巧算方法
//n!低位0的个数
int main()
{
int t,i,n,m,z;
scanf("%d", &t);
for (i = 0; i < t; i++){
scanf("%d", &n);
m = 5;z = 0;
while (n >= m){
z += n / m;
m *= 5;
}
printf("case #%d:\n%d\n", i, z);
}
return 0;
}
//n!最高位
int main()
{
int n,fn;
double log_n_fac;
while (scanf("%d", &n) != EOF){
log_n_fac = 0.5 * log10(2 * PI *(double)n) + (double)n * log10((double)n / E);
log_n_fac -=(int)log_n_fac;
fn = pow(10, log_n_fac);//Stirling's approximation
switch(n){
case 0:printf("1\n");break;
case 1:printf("1\n");break;
case 2:printf("2\n");break;
case 3:printf("6\n");break;
case 7:printf("5\n");break;
case 8:printf("4\n");break;
default:printf("%d\n", fn);
}
}
return 0;
}
//n^n最高位
int main()
{
int n;
scanf("%d",&n);
while(n != 0){
printf("%d\n",(int)pow(10,n*log10(n)-(int)(n*log10(n))));
scanf("%d",&n);
}
return 0;
}
质因子分解
int n;
void solve(){
int i;
int m = n;
for (i = 2; i <= n; i++){
int cnt = 0;
if (m % i) continue;
while (m % i == 0){
m /= i;
cnt++;
}
printf("(%d,%d)", i, cnt);
if (m == 1) break;
}
printf("\n");
}
最长回文子串
//中心扩展法
string expand(string s, int c1, int c2) {
int l = c1, r = c2;
int n = s.size();
while (l >= 0 && r <= n-1 && s[l] == s[r])
l--, r++;
return s.substr(l+1, r-l-1);
}
string lps(string s) {
int n = s.size();
if (!n) return "";
string lungo = s.substr(0, 1);
for (int i = 0; i < n-1; i++) {
string p1 = expand(s, i, i);
if (p1.size() > lungo.size())
lungo = p1;
string p2 = expand(s, i, i+1);
if (p2.size() > lungo.size())
lungo = p2;
}
return lungo;
}
最大区间和
ans = a[0];
for (i = 0; i < n; ++i){
if (tot > 0) tot += a[i];
else tot = a[i];
ans = (tot>ans)?tot:ans;
}
小型分数模板
struct frac
{
ll nume, deno;
ll gcd(ll a, ll b)
{
a = abs(a); b = abs(b);
return b ? gcd(b, a % b) : a;
}
void reduct()
{
if(!nume) {
deno = 1;
return;
}
ll g = gcd(nume, deno);
nume /= g; deno /= g;
return;
}
frac(ll a, ll b = 1)
{
nume = a; deno = b;
(*this).reduct();
}
void print()
{
if(deno == 1) printf("%lld\n", nume);
else printf("%lld/%lld\n", nume, deno);
}
};
frac operator+(const frac& a, const frac& b)
{
frac ret(a.nume*b.deno + b.nume*a.deno, a.deno*b.deno);
ret.reduct();
return ret;
}
简单DP
//01背包
for (i = 0; i < n; ++i)
for (j = m; j >= w[i]; --j)
dp[j] = max(dp[j], dp[j-w[i]] + c[i]);
//最大上升子序列和(n^2)
for (i = 0; i < n; ++i)
dp[i] = a[i];
nowmax = a[0];
for (i = 0; i < n; ++i)
for (int j = 0; j < i; ++j)
if (a[j] < a[i])
{
dp[i] = max(dp[i], dp[j] + a[i]);
nowmax = max(nowmax, dp[i]);
}
//整数拆分
for (i = 1; i <= n; ++i)
for (j = 2; j <= n; ++j)
{
dp[i][j] = dp[i][j - 1];
if (i == j) ++dp[i][j];
else if(i > j) dp[i][j] += dp[i - j][j];
}
//拆成2的幂和
for (int i = 3; i <= 1000000; ++i)
{
if (i & 1) dp[i] = dp[i-1] % mod;
else dp[i] = (dp[i-2] + dp[i>>1]) % mod;
}
//拆成不重复正整数
dp[0] = 1;
for (int i = 1; i <= m; ++i)
for (int j = n; j >= i; --j)
dp[j] += dp[j-i];
//数塔(和最小)
for (i = n-1; i >= 0; --i)
for (j = 0; j <= i; ++j)
dp[j] = min(dp[j], dp[j+1]) + a[i][j];
//数塔(和的个位数最大)
for (i = 0; i < n; ++i)
dp[n-1][i][a[n-1][i] % 10] = 1;
for (i = n-2; i >= 0; --i)
for (j = 0; j <= i; ++j)
for (k = 0; k < 10; ++k)
if (dp[i+1][j][k] || dp[i+1][j+1][k])
dp[i][j][(k + a[i][j]) % 10] = 1;
for (i = 9; i >= 0; --i)
if (dp[0][0][i]){printf("%d\n", i); break;}
//装箱问题(dp)
for (i = 0; i < n; ++i)
{
scanf("%d", &w);
for (j = m; j >= w; --j)
dp[j] = max(dp[j], dp[j-w] + w);
}
//装箱问题(搜索)
void dfs(int cnt, int now)
{
if (now > v) return;
if (cnt == n + 1){
if (now > max) max = now;
return;
}
dfs(cnt + 1, now);
dfs(cnt + 1, now + a[cnt]);
}
十六进制加法
const int N = 233;
struct bigNum{
int a[N];
bigNum(){
memset(a,sizeof(a),0);
for (int i=0;i
}
void print(){
for (int i = a[0]; i>0; i--){
printf("%X",a[i]);
}
puts("");
}
bigNum operator + (const bigNum &b){
bigNum c;
c.a[0] = max(a[0], b.a[0]);
int x = 0;
for (int i=1;i<=c.a[0];i++){
//printf("b[i] = %d", b.a[i]);
x += a[i] + b.a[i];
c.a[i] = x % 16;
x /= 16;
}
if (x) c.a[++c.a[0]] = x;
return c;
}
}a, b;
int qd(char x){
if ('0' <= x && x <= '9')return x - '0';
return x - 55;
}
bigNum jd(string st){
bigNum ans;
ans.a[0] = st.length();
for (int i=1; i <= ans.a[0]; i++){
ans.a[i] = qd(st[ans.a[0] - i]);
}
return ans;
}
int main(){
int T;scanf("%d", &T);
string st1, st2;
for (int cas = 0;cas < T;cas++){
printf("case #%d:\n", cas);
cin >> st1 >> st2;
a = jd(st1);
b = jd(st2);
bigNum c = a + b;
c.print();
}
return 0;
}
部分库函数
int isgraph(int ch) 是否是可打印字符(不含空格)
int isprint(int ch) 是否是可打印字符(含空格)
int ispunct(int ch)
double atan2(double y, double x) y/x的反正切(弧度)
int atoi(char *nptr)
double strtod(char *str)
int sscanf(char str, char *format) 通过str格式化赋值
char strcpy(char* dest, char* src)
char strcat(char* dest, char* src)
char strchr(const char *s1, int c)
int strcmp(const char* s1, const char* s2) 返回s1-s2
int strncmp(const char* s1, const char* s2, size_t maxlen)
char strrev(char *s)
char strstr(const char* s1, const char* s2) s2中第一次出现s1的位置
string s(cstr[, chars_len]);
string s(num, c);
{
string s(“abcd”);
s.compare(“abcd”); //0
s.compare(“dcba”); //<0
s.compare(“ab”); //>0
s.compare(0,2,s,2,2); //比较ab和cd <0
}
s.assign(“nico”,5);//’n’’i’’c’’o’’\0’
s.insert(1,str);//插入到索引前
s.replace(1,2,”nternationalizatio”);//从1开始的2个s.erase(13);//从13开始往后全删除
s.erase(7,5);//从7开始往后删5个
string::find系列:
1. 搜索对象
2. [起点索引]
3. [搜索字符个数]
编程注意点
1.一般用C语言节约空间,要用C++库函数或STL时才用C++;
cout、cin和printf、scanf最好不要混用。
2.有时候int型不够用,可以用long long或__int64型(两个下划线__)。
值类型表示值介于 -2^63 ( -9,223,372,036,854,775,808) 到2^63-1(+9,223,372,036,854,775,807 )之间的整数。
printf("%I64d",a);
printf("%lld",a);
3.OJ判断是只看输出结果的。
所以大部分题处理一组数据后可以直接输出,就不需要用数组保存每一个Case的数据。
while(case--)
{scanf(...);
......
printf(...);
}
4.纯字符串用puts()输出。
数据大时最好用scanf()、printf()减少时间。
先用scanf(),再用gets()会读入回车。
scanf("%c%c",&c1,&c2)会读入空格;
5. 读到文件的结尾,程序自动结束
while( ( scanf(“%d”,&a) ) != -1 )
while( ( scanf(“%d”,&a) ) != EOF)
while( ( scanf(“%d”,&a) ) == 1 )
读到一个0时,程序结束
while( scanf(“%d”,&a) &&a)
读到多个0时,程序结束
while( scanf(“%d%d%d”,&a,&b,&c)&&a+b+c )
6.数组定义int a[10]={0};可以对其全部元素赋值为0;
全局变量,静态变量自动初始化为0;
7.有很多数学题是有规律的,直接推公式或用递归、循环。
8.圆周率=cos(0.0)
自然对数=exp(1.0)
9.如果要乘或除2^n,用位移运算速度快。a>>n;a<<n;
10.定义数组时,数组大小最好比告诉的最大范围大一点。字符数组大小必须比字符串最大长度大1。处理字符数组时不要忘了在最后加'\0'。
11.擅用三目运算符
int max(int a,int b)
{return a>b?a:b;
}
int gcd(int m,int n)
{return n?gcd(n,m%n):m;
}
int abs(int a)
{return a<0?-a:a;
}
12.将乘法转换成加法减少时间
log(a*b)=log(a)+log(b)
将乘法转换成除法防止溢出
a/(b*c)=a/b/c
13.排序要求不高时可以用C++的STL模板函数sort(),stable_sort()
int a[n]={...};
sort(a,a+n);
bool cmp(int m,int n)
{return m>n;
}
sort(a,a+n,cmp);
14.有的题数据范围小但是计算量大可以用打表法
先把结果算出来保存在数组里,要用时直接取出来。
1.输入输出
ACM和TopCoder不同,TopCoder只用让参赛者写一个class,而ACM需要参赛者完成整个console程序.在TopCoder中,输入输出是通过parameter传递的,不用过多考虑,在ACM中,却需要自己编写.
(1).只有一组输入时,这种情况不用我说了,都会,但是通常也不会有这么水的题
(2).固定组数的输入,可以利用一个计数器和while语句完成,
01 #include <iostream>
02
03 int main(void){
04 int n;
05 scanf("%d", &n);
06 while (n--){
07 //...
08 }
09 //...
10 return 0;
11 }
(3).测试数据结尾有标志字符(例如最后一组输入后给一个0),这个只用加一个if语句判断读入的数据是什么,是结束标志跳出就ok了.也不多说了
(4).题目没有告诉你有多少组数据,这个通常是最令新手疑惑的,这种情况,一般用文件结束标志EOF判断
01 #include <iostream>
02
03 int main(void){
04 int n;
05 while (scanf("%d", &n) != EOF){
06 //...
07 }
08 //...
09 return 0;
10 }
其实这里也可以用c++的cin输入流判断,例如
01 #include <iostream>
02
03 using namespace std;
04
05 int main(void){
06 int n;
07 while (cin>>n){
08 //...
09 }
10 //...
11 return 0;
12 }
但是这样不是特别好,为什么?下面会说.
对于输出,最好采用的接收一组数据,处理一组数据,把结果保存在一个缓冲数组中,待所有输入结束后,再一起输出,而不是待接收完所有输入后,再处理,再输出,这样会消耗更多的memory,而且会更慢.
2.关于效率
第一,上面的所有例子,均采用的c标准I/O,为什么不用c++的cin,cout呢?是有原因的,经实践,在大规模输入输出下,cin,cout效率远远低于scanf()和printf(),原因据我估计应该是以为scanf(),printf()是汇编写的(这点可以从这两个函数均可以接受任意多组parameter(s)看出,c/c++函数是不具备这样的性质的),而cin,cout均是直接c/c++写的流操作,本来c/c++就比汇编慢,还引入流,所以自然比scanf(),printf()慢了.因此,在输入输出数据量很小的情况下,出于方便的原因,可以采用cin,cout,而在输入输出数据量比较大的情况下用scanf(),printf()比较保险,避免超时.
第二.ACM中,除了c/c++,一般还支持java等语言,但是由于java是解释执行的,效率十分低下,为此,一般的JudgeOnline都把java的time limit设置为题目给定值(也就是c/c++的time limit)的三倍,而且给每一组输入再额外提供150ms.即使是这样,java遇上复杂或者高精度计算的题目,还是很容易超时,因为效率有时候还远远未到c/c++的1/3.因此,一般来说,除了个别java极其有利的情况(例如字符串处理),不建议使用java.
3.关于调试
(1)调试的时候可以使用重定向,从文件中读入数据、直接将答案输出到文件中。
例如:
以读的方式打开输入文件:freopen(“txtin.txt”,”r”,stdin);
以写的方式打开输出文件:freopen(“txtin.txt”,”w”,stdout);
但是需要注意的是,再提交代码的时候一定要记得将以上两句与文件操作有关的代码去掉,否在系统会因找不到对应的文件而出错。
(2)题目一般给出的测试数据都是较少的,为了验证程序的正确性,要自己多设几组测试数据,尤其不要忘记了边界值的处理,边界往往会是容易出错的地方。
(3)再写计算公式的时候,若等式两边的类型不一样要特别注意类型转换,否常常会得到一个错误的结果。比如,int a,b; double c;
c=a/b;若a可以整除b则答案是正确的,否在a/b的结果只取结果的整数部分,并不会自动转换为double类型。正确的写法应该是c=(double)a/b,这样才会得到正确的答案。
还有再调用一些数学函数的时候,比如floor(),应该注意的是其参数是double型的,再调用时应该写为floor((double)a/b);否在a/b自动取整,floor函数并不起作用。