A 學姐的桌面
連結:http://code.bupt.edu.cn/problem/p/413/
思路:水題,有一個坑就是怎麼輸出“%”這個字元,當時沒注意到自己的程式沒打這個字元直接交了上去wa了一次。
code:
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <algorithm>
#include <cmath>
#define INF 10000
using namespace std;
const int MAX_N=1000;
const int MAX_M=1000;
int main()
{
int T,n,t,nn,mid;
double ans;
scanf("%d",&T);
while(T--){
scanf("%d%d",&n,&t);
nn=0;
for(int i=0;i<n;i++){
scanf("%d",&mid);
if(mid<t) nn++;
}
ans=(double)nn/n;
printf("%.2lf",ans*100);
printf("%c",'%');
printf("\n");
}
return 0;
}
B 學姐去學車
連結:http://code.bupt.edu.cn/problem/p/414/
思路:找規律的題,多寫幾項就能看出來,當時1A了,具體規律見代碼吧。
code:
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <algorithm>
#include <cmath>
#define INF 10000
using namespace std;
const int MAX_N=1000;
const int MAX_M=1000;
int main()
{
int T,n,m,q,tt;
scanf("%d",&T);
while(T--){
scanf("%d%d",&n,&m);
scanf("%d",&tt);
while(tt--){
scanf("%d",&q);
if(q<=n) printf("1\n");
else if(q%(n+1)<m) printf("2\n");
else printf("1\n");
}
}
return 0;
}
當時就做出來了這兩個題,太弱了~~
C 學姐的學弟
連結:http://code.bupt.edu.cn/problem/p/415/
大緻題意:給多個圓每個圓的坐标都是整數,且半徑都是1,求這幾個圓的并。
思路:比賽時感覺這個題得用計算幾何做,計算幾何根本一竅不通就沒再想,後來聽學長講,這個題有幾個關鍵的地方(坐标為整數 半徑為一) 是以圖上每個小方格的情況一共隻有三種:全部覆寫,
,
。
這三種情況其面積分别為
再統計個數的時候以左上角為準,如果四個頂點中有一條對角線上的兩個頂點是圓心則為第一種,如果隻有一個頂點是圓心是第二種,有兩個頂點在一條邊上是第三種,然後周遊所有頂點統計個數即可。
code:
//2014 排位賽01 C(奇葩方法求面積)
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<cstring>
#include<queue>
#include<cmath>
#include<algorithm>
#define INF 1000000000
using namespace std;
const int MAX_N=130;
const int MAX_E=500005;
const double Pi=acos(-1.0);
const double s1=Pi/4,s2=Pi/6+sqrt(3.0)/4,s3=1;
bool graph[MAX_N][MAX_N];
int n1,n2,n3;
int main()
{
int T,n;
double res;
scanf("%d",&T);
while(T--){
scanf("%d",&n);
n1=n2=n3=0;
for(int i=0;i<MAX_N;i++) for(int j=0;j<MAX_N;j++) graph[i][j]=0;
for(int i=0;i<n;i++){
int x,y;
scanf("%d%d",&x,&y);
graph[x][y]=1;
}
for(int i=0;i<MAX_N-10;i++){
for(int j=0;j<MAX_N-10;j++){
//printf("i=%d j=%d..\n",i,j);
if((graph[i][j]&&graph[i+1][j+1])||
(graph[i+1][j]&&graph[i][j+1])) n3++;
else if((graph[i][j]&&graph[i][j+1])||
(graph[i][j]&&graph[i+1][j])||
(graph[i+1][j]&&graph[i+1][j+1])||
(graph[i][j+1]&&graph[i+1][j+1])) n2++;
else if(graph[i][j]||graph[i][j+1]||graph[i+1][j]||graph[i+1][j+1]) n1++;
}
}
//printf("n1=%d n2=%d n3=%d..\n",n1,n2,n3);
res=n1*s1+n2*s2+n3*s3;
printf("%.5lf\n",res);
}
return 0;
}
D BLOCKS
連結:http://code.bupt.edu.cn/problem/contest/104/problem/D/
思路:這個當時做了好久一直是re,比賽結束之後又改了幾次還是re(無語了),無奈。
當時的思路是判斷相關的‘#’圖中是否存在一個點四周的非‘#’是否等于三,如果等于三則不為矩形(這裡面有個特殊情況就是寬為1的條需要特殊判斷),否則就是矩形。
一直re呀,後來重寫改了一種更簡單的思路: 周遊整個‘#’圖,記錄其中x,y的最大值和最小值,根據最大最小值可以計算一下矩形的面積,再搜尋的時候記錄一下‘#’的個數看二者是否相等如果相等就是矩形,否則就不是,并且将dfs改成bfs,用手寫隊列來代替stl,十分利索,一次就a掉了。
code:
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <algorithm>
#include <cmath>
#define INF 10000
using namespace std;
const int MAX_N=1010;
const int MAX_M=1000002;
char graph[MAX_N][MAX_N];
int dir[4][2]={{1,0},{-1,0},{0,1},{0,-1}};
int N,M;
struct ppp{int x,y;} P[MAX_M];
int head,tail;
bool bfs(int x,int y)
{
graph[x][y]='0';
int minx=x,miny=y,maxx=x,maxy=y,nn=1;
head=tail=0;
P[tail].x=x;
P[tail++].y=y;
while(head!=tail){
int xx=P[head].x,yy=P[head++].y;
for(int i=0;i<4;i++){
int midx=xx+dir[i][0],midy=yy+dir[i][1];
if(midx<0||midy<0||midx>=N||midy>=M) continue;
if(graph[midx][midy]=='#'){
nn++;
minx=min(minx,midx);
miny=min(miny,midy);
maxx=max(maxx,midx);
maxy=max(maxy,midy);
graph[midx][midy]='0';
P[tail].x=midx;
P[tail++].y=midy;
}
}
}
if((maxx-minx+1)*(maxy-miny+1)==nn) return true;
return false;
}
void solve()
{
int nn=0;
for(int i=0;i<N;i++){
for(int j=0;j<M;j++){
if(graph[i][j]=='#'){
if(!bfs(i,j)){
printf("So Sad\n");
return ;
}
else nn++;
}
}
}
printf("There are %d ships.\n",nn);
return ;
}
int main()
{
while(scanf("%d%d",&N,&M)!=EOF){
for(int i=0;i<N;i++) scanf("%s",graph[i]);
solve();
}
return 0;
}
E 數的關系
連結:http://code.bupt.edu.cn/problem/p/409/
思路:遞推的方法dp[i][j]=(j+1)*(dp[i-1][j]+dp[i-1][j-1]) dp[i][j] 表示i個數,用j個<号來連結,可以構成的個數。可以讨論第i個數是以什麼
方式更前面i-1個數連結的,如果是‘=’有j+1種,如果是‘<’号也有j+1種,可得遞推式,這題的一個麻煩之處就是資料規模太大得用高精度,直接
套用了一個高精度類水過了。
code:
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#define INF 10000
using namespace std;
const int MAX_N=105;
const int MAX_M=100;
const int maxn = 200;
struct bign{
int len, s[maxn];
bign() {
memset(s, 0, sizeof(s));
len = 1;
}
bign(int num) {
*this = num;
}
bign(const char* num) {
*this = num;
}
bign operator = (int num) {
char s[maxn];
sprintf(s, "%d", num);
*this = s;
return *this;
}
bign operator = (const char* num) {
len = strlen(num);
for(int i = 0; i < len; i++) s[i] = num[len-i-1] - '0';
return *this;
}
string str() const {
string res = "";
for(int i = 0; i < len; i++) res = (char)(s[i] + '0') + res;
if(res == "") res = "0";
return res;
}
bign operator + (const bign& b) const{
bign c;
c.len = 0;
for(int i = 0, g = 0; g || i < max(len, b.len); i++) {
int x = g;
if(i < len) x += s[i];
if(i < b.len) x += b.s[i];
c.s[c.len++] = x % 10;
g = x / 10;
}
return c;
}
void clean() {
while(len > 1 && !s[len-1]) len--;
}
bign operator * (const bign& b) {
bign c; c.len = len + b.len;
for(int i = 0; i < len; i++)
for(int j = 0; j < b.len; j++)
c.s[i+j] += s[i] * b.s[j];
for(int i = 0; i < c.len-1; i++){
c.s[i+1] += c.s[i] / 10;
c.s[i] %= 10;
}
c.clean();
return c;
}
bign operator - (const bign& b) {
bign c; c.len = 0;
for(int i = 0, g = 0; i < len; i++) {
int x = s[i] - g;
if(i < b.len) x -= b.s[i];
if(x >= 0) g = 0;
else {
g = 1;
x += 10;
}
c.s[c.len++] = x;
}
c.clean();
return c;
}
bool operator < (const bign& b) const{
if(len != b.len) return len < b.len;
for(int i = len-1; i >= 0; i--)
if(s[i] != b.s[i]) return s[i] < b.s[i];
return false;
}
bool operator > (const bign& b) const{
return b < *this;
}
bool operator <= (const bign& b) {
return !(b > *this);
}
bool operator == (const bign& b) {
return !(b < *this) && !(*this < b);
}
bign operator += (const bign& b) {
*this = *this + b;
return *this;
}
};
istream& operator >> (istream &in, bign& x) {
string s;
in >> s;
x = s.c_str();
return in;
}
ostream& operator << (ostream &out, const bign& x) {
out << x.str();
return out;
}
bign dp[MAX_N][MAX_N];
bign ans[MAX_N];
int main()
{
int n;
for(int i=1;i<=100;i++){
ans[i]="0";
dp[i][0]="1";
for(int j=1;j<i;j++) dp[i][j]="0";
}
for(int i=2;i<=100;i++){
for(int j=1;j<=i-1;j++){
for(int k=0;k<j+1;k++) dp[i][j]+=(dp[i-1][j]+dp[i-1][j-1]);
}
}
for(int i=1;i<=100;i++){
for(int j=0;j<i;j++){
ans[i]+=dp[i][j];
}
}
while(scanf("%d",&n)!=EOF){
cout<<ans[n]<<endl;
}
return 0;
}
到此為止就是這樣,加油!!