1.different triangs
題目大意:給出n條邊,任取其中三條,問有多少種情況取出的三條邊能組成三角形。
解:先使用數組把邊長存起來,然後用三重循環去枚舉取邊方案,再用if語句判斷取出的三條邊是否能組成三角形(我使用了函數實現這個功能)
代碼:
#include <cstdio>
#include <iostream>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <cstdlib>
using namespace std;
bool check(int a, int b, int c){
if ((a+b>c)&&(a+c>b)&&(b+c>a)) return true;
return false;
}
int main(){
int n, cas, a[1111];
cin>>cas;
while (cas--){
cin>>n;
for (int i=1; i<=n; i++) cin >> a[i];
int ans=0;
for (int i=1; i<=n-2; i++)
for (int j=i+1; j<=n-1; j++)
for (int k=j+1; k<=n; k++)
if (check(a[i], a[j], a[k])) ans++;
cout << ans << endl;
}
return 0;
}
2.矩形邊框
題目大意:給出矩形的寬度和高度,輸出由*號圍成的矩形邊框.
解:很容易發現,其實除了行數爲1,h,列數爲1,w的方格應該是*號外,其他都是空格,所以用if處理輸出即可。
代碼:
// Problem#: 12074
// Submission#: 3157183
// The source code is licensed under Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License
// URI: http://creativecommons.org/licenses/by-nc-sa/3.0/
// All Copyright reserved by Informatic Lab of Sun Yat-sen University
#include <cstdio>
#include <iostream>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <cstdlib>
using namespace std;
int main(){
int n, cas, m;
cin>>cas;
while (cas--){
cin>>m>>n;
for (int i=1; i<=n; i++){
for (int j=1; j<=m; j++){
if (i==1 || i==n || j==1 || j==m) cout <<'*';
else cout <<' ';
}
cout << endl;
}
cout << endl;
}
return 0;
}
3.分解質因數
題目大意:把每個輸入的數進行質因數拆分
解:暴力拆分也不會超時,不過其實枚舉質因數的時候枚舉到根號n就可以退出了(但是這樣做記得要枚舉自己因爲自己可能是一個質數)
代碼:(這題因爲讀錯題少行末沒有輸出空格PE了一次囧)
#include <cstdio>
#include <iostream>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <cstdlib>
using namespace std;
int main(){
int n;
cin>>n;
while (n--){
int now;
cin>>now; int sum=0, i=2;
while (now>1){
while (now%i==0){
sum++;
cout << i;
cout <<' ';
now/=i;
}
i++;
}
cout << endl;
}
return 0;
}
4.ELLIPSE
題目大意:給出一個橢圓,問有多少個整點(比如x,y是整點的充要條件是x,y都是整數)嚴格在橢圓內部(橢圓上的點不算)
解:相信判斷點是否在橢圓內的公式大家都會吧,所以暴力枚舉整數點就可以了,但是如果枚舉題目範圍內所有的點感覺太暴力不知道會不會跪(這是我當時的想法,現在算一算貌似不會跪>W<),我就加了一個小優化。給出焦點和長半軸長d後,可知整點一定不會小於左焦點橫座標減d(最壞情況,哪怕焦點重合,若整點座標小於左焦點橫座標減d,整點到兩焦點距離必然大於d),同理可以算出其他邊界。我繼續使用函數求距離因爲看起來會舒服一些。沒學過的同學可以試着模仿一下,相信你會喜歡這種風格的。
哦對了,我求最大最小值沒有用algorithm庫裏的max和min函數,而是我自己用define定義了這樣的寫法,有興趣學習的同學可以搜索一下define的用途以及三元運算符“ a?b:c”
擦再看一眼貌似struct大家不知道用過沒= =,不會的就問我,不要打我(抱頭)
代碼:
#include <cstdio>
#include <iostream>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <cstdlib>
#define SQR(x) ((x)*(x))
#define MIN(a,b) (a<b?a:b)
#define MAX(a,b) (a>b?a:b)
using namespace std;
struct point{double x, y;};
double dist(point a, point b){
return sqrt(SQR(a.x-b.x)+SQR(a.y-b.y));
}
int main(){
int n, cas, m;
cin>>cas;
while (cas--){
point f1, f2;
int d;
cin>>f1.x>>f1.y>>f2.x>>f2.y>>d;
int x1, x2, y1, y2;
x1=MIN(f1.x, f2.x); x2=MAX(f1.x, f2.x);
y1=MIN(f1.y, f2.y); y2=MAX(f1.y, f2.y);
x1-=d; x2+=d;
y1-=d; y2+=d;
int ans=0;
for (int x=x1; x<=x2; x++)
for (int y=y1; y<=y2; y++){
point tmp; tmp.x=x; tmp.y=y;
if ((dist(f1, tmp)+dist(f2, tmp))<d) ans++;
}
cout << ans << endl;
}
return 0;
}
5.Prime Palindromes
題目大意:求區間[a,b]內的迴文數素數
爲什麼要出這道題!!!!!
解:吭,跑題了。這道題感覺大家第一時間會傾向於暴力枚舉,但參見我上一篇文章,算複雜度的事情,因爲這裏b可以去到1億的,出數據的人和(喪)藹(心)可(病)親(狂)一點出幾個[5,100000000]的數據程序就tle了,所以我們不能這樣暴力做。
那麼如何優化呢?其實我們可以利用迴文數的性質很好地吧複雜度優化下來。因爲爲啥不用枚舉全部的數呢?因爲我們需要的僅僅是迴文數,而回文數知道了左半邊即可知道右半邊了。對了,我們枚舉左半邊的數就好了,哪怕是九位數,我們也只需要枚舉1~99999即可,如此我們便將複雜度從O(n)變成了O(根號n)。把迴文數求出來了便求一下是否素數就好(相信大家都會,而且我依舊是用函數實現)
PS:
當然此題存在很多細節討論,比如我枚舉生產後發現答案不是單調遞增的,所以我先把答案保存然後排序輸出。因爲考慮到大家沒有學到數組,我就沒有用拆位放入數組翻轉的方法實現還原迴文數,而是直接用數學方法(最後還是用到了數組TAT,但是你們相信我這題理論上我的方法還是不要用到數組的,跟別的組長比起來用什麼dfs還有打表這種高科技我自認爲我還是很有節操的(⊙o⊙)。想學習高科技的同學可以搜索 遞歸,打表的話私聊問吧,因爲我覺得只算技巧而不是什麼數據結構啊算法這方面的東西) 而翻轉回文數的時候要用到10的n次方冪,因此我沒有每一次都pow一下而是先預處理把要用到的次方冪保存。
PS2:我的註釋語句是我調試用的,想了一下沒有刪掉,在最後附一個刪註釋版。不會調試的可以參考下,另外sort的函數可以接觸一下,理解原理不太容易但是會用還是挺簡單的)
代碼:
#include <cstdio>
#include <iostream>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <cstdlib>
#define SQR(x) ((x)*(x))
#define MIN(a,b) (a<b?a:b)
#define MAX(a,b) (a>b?a:b)
using namespace std;
struct point{double x, y;};
bool check(int x){
for (int i=2; i<=trunc(sqrt(x)); i++)
if (x%i==0) return false;
return true;
}
int aa[1000000];
long long poww[13];
int main(){
poww[0]=1;
for (int i=1; i<=12; i++) poww[i]=poww[i-1]*10;
long long a, b, now, tot;
while (cin>>a>>b && a+b>0){
tot=0;
for (int lab=1; lab<=9; lab++){
if (poww[lab-1]>b) break;
// cout <<'!' << lab << endl;
int lim=poww[(lab+1)/2]-1;
// cout << lim << endl;
for (int i=1; i<=lim; i++)if (i%2==1){
now=i;
// cout << i << endl;
for (int j=1; j<=lab; j++){
if (lab-j+1 == j) break;
long long tt=(i/poww[j-1]);
// cout << tt << endl;
now+=(poww[lab-j])*(tt%10);
}
// cout << i <<' '<< now << endl;
if ((now>=a)&&(now<=b)&&(check(now))) {
aa[++tot]=now;
}
}
}
sort(aa+1, aa+1+tot);
for (int i=1; i<=tot; i++)
if (aa[i]>1) printf("%d\n", aa[i]);
}
return 0;
}
無註釋版:
#include <cstdio>
#include <iostream>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <cstdlib>
#define SQR(x) ((x)*(x))
#define MIN(a,b) (a<b?a:b)
#define MAX(a,b) (a>b?a:b)
using namespace std;
struct point{double x, y;};
bool check(int x){
for (int i=2; i<=trunc(sqrt(x)); i++)
if (x%i==0) return false;
return true;
}
int aa[1000000];
long long poww[13];
int main(){
poww[0]=1;
for (int i=1; i<=12; i++) poww[i]=poww[i-1]*10;
long long a, b, now, tot;
while (cin>>a>>b && a+b>0){
tot=0;
for (int lab=1; lab<=9; lab++){
if (poww[lab-1]>b) break;
int lim=poww[(lab+1)/2]-1;
for (int i=1; i<=lim; i++)if (i%2==1){
now=i;
for (int j=1; j<=lab; j++){
if (lab-j+1 == j) break;
long long tt=(i/poww[j-1]);
now+=(poww[lab-j])*(tt%10);
}
if ((now>=a)&&(now<=b)&&(check(now))) {
aa[++tot]=now;
}
}
}
sort(aa+1, aa+1+tot);
for (int i=1; i<=tot; i++)
if (aa[i]>1) printf("%d\n", aa[i]);
}
return 0;
}