}
1002. Square
解:我的做法是把四條邊化作從原點爲起點的向量,然後先判斷向量是否長度都是一樣,先確定這個四邊形是一個菱形,然後一個菱形是正方形的充要條件是其中有一個直角即可,而需找直角的公式題目當中最下方也已經給出來了。代碼:
#include <cstdio>
#include <iostream>
#include <cmath>
#include <algorithm>
using namespace std;
#define SQR(x) ((x)*(x))
#define EPS (1e-8)
struct point{int x, y;};
bool flag;
point a[10], b[10];
bool check(){
double dist=sqrt(SQR(b[1].x) + SQR(b[1].y));
for (int i=2; i<=4; i++){
double tmp=sqrt(SQR(b[i].x) + SQR(b[i].y));
if (abs(tmp-dist)>EPS) return false;
}
if (abs(b[1].x*b[2].x+b[1].y*b[2].y)>EPS) return false;
return true;
}
int main(){
for (int i=1; i<=4; i++){
scanf("%d%d", &a[i].x, &a[i].y);
}
a[5]=a[1];
for (int i=1; i<=4; i++){
b[i].x=a[i+1].x-a[i].x;
b[i].y=a[i+1].y-a[i].y;
}
flag=check();
if (flag) cout << "Yes\n";
else cout << "No\n";
return 0;
}
1003. Array
解:前綴和的變形,分別求出奇數項的前綴和和偶數項的前綴和即可~。這樣就能快速查詢某個區間的權值和了。詳細可以參考代碼實現。代碼中b數組記錄奇數前綴和,c數組記錄偶數前綴和,而a就是記錄讀入初始數組。 代碼:
#include <cstdio>
#include <iostream>
#include <cmath>
using namespace std;
#define MAXN 1111
int a[MAXN]={0}, b[MAXN]={0}, c[MAXN]={0};
int n,m;
int main(){
cin>>n;
for (int i=1; i<=n; i++){
scanf("%d", &a[i]);
}
for (int i=1; i<=n; i++){
b[i]+=b[i-1]; c[i]+=c[i-1];
if (i&1==1) b[i]+=a[i];
else c[i]+=a[i];
}
//for (int i=1; i<=n; i++) cout << b[i] << endl;
cin>>m;
int x,y;
while (m--){
scanf("%d%d", &x, &y);
//cout << b[y]-b[x-1] << endl;
//cout << c[y]-c[x-1] << endl;
int tmp=abs((b[y]-b[x-1])-(c[y]-c[x-1]));
printf("%d\n", tmp);
}
return 0;
}
PS:註釋起來的語句是用來調試用的,我發現了一個細節問題就是<cmath>和<algorithm>庫裏貌似都有abs函數,但是他們的用法和實現有點不一樣的。建議使用algorithm裏的abs函數。在本地做得時候這題因爲這個問題掛了。
1004. Polynomial
解:大魔王題目。很多人用枚舉來做,枚舉每個多項式內選取ax項還是b項然後乘起來。其實我感覺這樣做就很笨拙了。其實就模擬人手工展開多項式就好了比如 (x+2)(x+3) 不要用什麼十字相乘,你用筆紙算算看步驟?其實可以提出出係數 (1, 2)*(1, 3)可以看作 1 2 * 1 3 ———————— 3 6 1 2 ———————— 1 5 6答案是 x^2+5x+6,是不是呢?wzm大神總結得好(你們看好了是wzm不是wmz,不是我!)其實這個問題的本質可以看做不進位的乘法就好了。那麼我的程序就直接模擬了這個乘法過程,輸出的時候注意符號,係數這些細節就ok啦!代碼:
#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
long long a[10][10]={0};
int n;
int main(){
cin>>n;
for (int i=1; i<=n; i++){
for (int j=1; j<=2; j++) scanf("%lld", &a[i][j]);
}
a[1][0]=2;
for (int k=2; k<=n; k++){
for (int i=1; i<=a[1][0]; i++){
for (int j=1; j<=2; j++){
a[0][i+j-1]+=a[1][i]*a[k][j];
}
}
a[1][0]++;
for (int i=1; i<=a[1][0]; i++){
a[1][i]=a[0][i];
}
for (int i=1; i<=9; i++) a[0][i]=0;
}
//cout << a[1][1] << endl;
long long tmp;
for (int i=1; i<=a[1][0]; i++){
tmp=abs(a[1][i]);
if (a[1][i]==0) continue;
if (a[1][i]<0) cout <<'-';
else {
if (i>1) cout <<'+';
}
if (i<a[1][0]){
if (tmp!=1) cout << tmp;
cout << 'x';
if (n-i+1>1) cout << '^'<<n-i+1;
}
else cout << tmp;
}
cout << endl;
return 0;
}
寫在最後:
考試有點像競賽,他不可能讓你慢慢悠悠地去做題,所以,有一些你平常可以發揮的能力就發揮不出來了。
那麼怎麼解決呢?就像我最開始講的,限制做題時間,訓練緊張感。
但是這不是根本解決問題的辦法,至少從我這種笨拙型的競賽選手看來,是不存在一種能夠排除做題在外而提高自己的思考和代碼實現能力的辦法的。
所以題目的練習數量一定要保證。如果想及格,那麼你必須能夠在程序設計課的兩節課以內就把課程作業做完。
而如果想追求優秀,那還遠遠不夠。
我曾經在一個大牛的博客內看到這樣一句簽名,很喜歡:
積羽沉舟,羣輕折軸。