NOJ刷题总结
+++
HDU1969 Pie
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#define P acos(-1.0)
using namespace std;
const int N = 10010;
int n, f, a[N];
bool more_pie(double u)
{
int cnt = 0;
for(int i = 0; i < n; i++ )
cnt += (int)(P * a[i] * a[i] / u);
if(cnt >= f + 1) return true;
else return false;
}
int main()
{
int t;
scanf("%d", &t);
while(t--)
{
int res = 0;
scanf("%d%d", &n, &f);
for(int i = 0; i < n; i++ ){ scanf("%d", a + i); res = max(res, a[i]);}
double L = 0, R = res * res * P;
while(R - L >= 1e-6)
{
double mid = (L + R) / 2;
if(more_pie(mid)) L = mid;
else R = mid;
}
printf("%.4lf
", R);
}
return 0;
}
HDU1087 super jump
//accode O(n²)
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 1010;
int a[N], dp[N];
int main()
{
int m;
while(cin >> m && m)
{
memset(dp, 0, sizeof dp);
for(int i = 1; i <= m; i++ )
{
scanf("%d", a + i);
dp[i] = a[i];
}
int res = a[1];
for(int i = 2; i <= m; i++ )
for(int j = 1; j < i; j++ )
if(a[i] > a[j]) {dp[i] = max(dp[i], dp[j] + a[i]); res = max(res, dp[i]);}
cout << res << endl;
}
return 0;
}
HDU1004
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <map>
#define x first
#define y second
using namespace std;
map<string,int>p;
int main()
{
int n;
while(scanf("%d",&n),n)
{
p.clear();
string s;
for(int i = 0; i < n; i++ )
{
cin >> s;
p[s]++;
}
int max=0;
string ss;
for(auto u : p)
if(u.y > max) {max = u.y; ss = u.x;}
cout<<ss<<endl;
}
return 0;
}
HDU1728 迷宫(坑死人的bfs)
卡了好几个小时
本来觉得普通的宽搜加上每步都判断是否转弯可以ac,结果样例都一直过不去。
之后就转变思路,一次搜索一个方向的所有点,直到撞墙或者到达边界,然后把符合条件的加入队列。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
const int N = 105;
int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1};
char g[N][N];
int vis[N][N];
int m, n;
int k, x1, y1, x2, y2;
struct Node
{
int x, y;
int cur;
}ss, ee;
void bfs(int x, int y)
{
memset(vis, 0, sizeof vis);
queue<Node> q;
vis[x][y] = 1;
ss.x = x, ss.y = y, ss.cur = -1;
q.push(ss);
while(q.size())
{
ss = q.front();
if(ss.cur >= k) break;
q.pop();
for(int i = 0; i < 4; i++ )
{
ee.x = ss.x + dx[i];
ee.y = ss.y + dy[i];
ee.cur = ss.cur + 1;
while(ee.x >= 0 && ee.x < m && ee.y >= 0 && ee.y < n && g[ee.x][ee.y] == '.')
{
if(ee.x == x2 && ee.y == y2 && ee.cur <= k)
{
cout << "yes" << endl;
return;
}
if(!vis[ee.x][ee.y])
{
vis[ee.x][ee.y] = 1;
q.push(ee);
}
ee.x += dx[i], ee.y += dy[i];
}
}
}
cout << "no" << endl;
return;
}
int main()
{
int t;
cin >> t;
while(t--)
{
scanf("%d%d", &m, &n);
for(int i = 0; i < m; i++ ) cin >> g[i];
cin >> k >> y1 >> x1 >> y2 >> x2;
y1--, x1--, y2--, x2--;
bfs(x1, y1);
}
return 0;
}
UVA10375
分子分母数字个数相同
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int main()
{
int p, q, r, s;
while(cin >> p >> q >> r >> s)
{
double ans = 1;
int i = 1, j = 1, x = p - q + 1, y = r - s + 1;
for(; i <= q || j <= s;)
{
if(i <= q) ans *= (double)x++ / i++;
if(j <= s) ans *= (double)j++ / y++;
}
printf("%.5f
", ans);
}
return 0;
}
UVA133
参考紫书代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 25;
int a[N], m, n, k;
int go(int p, int d, int t)
{
while(t--)
{
do
{
p = (p + d + n - 1) % n + 1;
}while(a[p] == 0);
}
return p;
}
int main()
{
while(cin >> n >> k >> m, n)
{
for(int i = 1; i <= n; i++ ) a[i] = i;
int left = n;
int p1 = n, p2 = 1;
while(left)
{
p1 = go(p1, 1, k);
p2 = go(p2, -1, m);
printf("%3d", p1);
left--;
if(p2 != p1) printf("%3d", p2), left--;
a[p1] = a[p2] = 0;
if(left) printf(",");
}
cout << endl;
}
return 0;
}
NOJ1041
线段叉乘
if(min(x3, x4) > max(x1, x2)
|| min(x1, x2) > max(x3, x4)
|| min(y1, y2) > max(y3, y4)
|| min(y3, y4) > max(y1, y2))
return false;
或者为了提高效率可以加上上面的代码,先粗略判断是否相交
#include <iostream>
using namespace std;
double x1, y1, x2, y2, x3, y3, x4, y4;
bool flag;
int main()
{
while (cin >> x1 >> y1 >> x2 >> y2 >> x3 >> y3 >> x4 >> y4)
{
double fa = (y1 - y3) * (x4 - x3) - (x1 - x3) * (y4 - y3);
double fb = (y2 - y3) * (x4 - x3) - (x2 - x3) * (y4 - y3);
double fc = (y3 - y1) * (x2 - x1) - (x3 - x1) * (y2 - y1);
double fd = (y4 - y1) * (x2 - x1) - (x4 - x1) * (y2 - y1);
if ((fc * fd < 0) && (fa * fb < 0))
flag = true;
else
flag = false;
if (flag)
cout << "yes" << endl;
else
cout << "no" << endl;
}
return 0;
}
-
堆排序
NOJ1066
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 100010;
int h[N], m, cnt, flag = 1;
void down(int u)
{
int t = u;
if(u * 2 <= cnt && h[u << 1] < h[t]) t = u << 1;
if(u * 2 + 1 <= cnt && h[u << 1 | 1] < h[t]) t = u << 1 | 1;
if(u != t)
{
swap(h[u], h[t]);
down(t);
}
}
int main()
{
cin >> m;
for(int i = 1; i <= m; i++ ) scanf("%d", h + i);
cnt = m;
for(int i = m >> 1; i; i--) down(i);
while(m--)
{
if(flag)
{ printf("%d", h[1]);
flag = 0;
}
else
printf(" %d", h[1]);
h[1] = h[cnt--];
down(1);
}
cout << endl;
return 0;
}