题目描述
小 D 是虔诚的嘟嘟教徒。现在小 G 送他了一幅著名画家芬达奇的作品。这是一幅 n n 的作品,由”.” 或者”#” 构成,其中”.” 相当于空白。但是现在小 D 怀疑小 G 送给他了一幅赝品。正版芬达奇的画作,是由若干个互不重叠的十字架拼起来的。每个十字架由五个”#” 组成,如下:
.#.
###
.#.
而赝品则不能将所有的”#” 分成若干个互不重叠的十字架,如:
.#..
####
.#..
特别地,如果一幅画里面全都是”.”,这仍然是一幅正品。
你的任务是帮助小 D 判断,小 G 送他的这幅画到底是不是正品。
输入格式
输入文件第一行一个数字 n,含义如题目所述。
第 2 行到第 n + 1 行,每行 n 个’.’ 或者’#’,描述整张画。
输出格式
输出文件一行,如果是正品,输出”YES”;如果是赝品,输出”NO”。
样例输入 1
5
.#...
####.
.####
...#.
.....
样例输出 1
YES
样例输入 2
4
####
####
####
####
样例输出 2
NO
数据范围
40% 数据,1 ≤n≤10
70% 数据,1 ≤n ≤50
100% 数据,1≤n ≤100
#include<iostream>
#include<queue>
#include<cstdio>
#include<cstring>
#define maxn 233
#define debug cout << "ok" << endl;
using namespace std;
char a[maxn][maxn];
bool used[maxn][maxn];
const int dx[] = {,,,-};
const int dy[] = {,,-,};
int n;
bool all_dot = true;
bool exist_remain_sharp = false;
bool check_in(int x,int y){
if (x >= && x<=n && y>= && y <=n)
return true;
else
return false; }
void n2_search(void){
for (int i=;i<=n;i++)
for (int j=;j<=n;j++){
if (a[i][j] == '.' || (a[i][j]=='#' && used[i][j]))
continue;
else{
bool now_check_fail = false;
for (int k=;k<;k++){
if (!check_in(i+dx[k],j+dy[k]) && a[i+dx[k]][j+dy[k]] == '.')
now_check_fail = true; }
if (!now_check_fail){
used[i][j] = true;
for (int k = ;k<;k++)
used[i+dx[k]][j+dy[k]] =true;
}
}
}
}
int main(){ freopen("puzzle.in","r",stdin);
freopen("puzzle.out","w",stdout);
scanf("%d",&n);
for (int i=;i<maxn;i++)
for (int j=;j<maxn;j++)
a[i][j] = '.';
for (int i=;i<=n;i++)
for (int j=;j<=n;j++){
cin >> a[i][j];
if (a[i][j]=='#')
all_dot =false;
}
if (all_dot){
printf("YES\n");
return ;
}
memset(used,false,sizeof(used));
n2_search();
for (int i=;i<=n;i++)
for (int j=;j<=n;j++){
if (a[i][j] == '#' && !used[i][j])
exist_remain_sharp = true; } if (exist_remain_sharp)
printf("NO\n");
else
printf("YES\n");
fclose(stdin);
fclose(stdout);
return ; }
然后是std:
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std; const int max_n = ;
int n;
bool a[max_n][max_n];
bool is_legal(int x, int y)
{
return <= x && x <= n && <= y && y <= n && a[x][y];
} int main()
{
freopen("puzzle.in", "r", stdin);
freopen("puzzle.out", "w", stdout);
cin >> n;
for (int i = ; i <= n; i++)
for (int j = ; j <= n; j++)
{
char c;
scanf(" %c", &c);
if (c == '#') a[i][j] = true;
} bool is_ok = true;
for (int i = ; i <= n; i++)
{
for (int j = ; j <= n; j++)
if (a[i][j])
{
if (is_legal(i + , j) && is_legal(i + , j - ) && is_legal(i + , j + ) && is_legal(i + , j))
{
a[i][j] = false;
a[i + ][j] = false;
a[i + ][j - ] = false;
a[i + ][j + ] = false;
a[i + ][j] = false;
}
else
{
is_ok = false;
break;
}
}
if (!is_ok) break;
} if (is_ok) cout << "YES" << endl;
else cout << "NO" << endl;
}
题目描述
小 Z 喜欢搭积木。小 Z 一共有 n 块积木,并且积木只能竖着一块一块的摞,可以摞多列。小 Z 的积木都是智能积木,第 i 块积木有一个情绪值 Xi。当摞在该积木上面积木总数超过 Xi 时,i 号积木就会不高兴。小 Z 情商这么高,肯定不希望有积木不高兴。但是他又希望每块积木都被用上,并且摞的积木列的总数最少。你能帮帮萌萌的小 Z 吗?
输入格式
输入文件第一行一个数字 n,含义如题目所述。
第 2 行一共 n 个数,第 i 个数为 Xi,含义如题目所述。
输出格式
输出一个数字,表示最小的积木列数目。
样例输入 1
3
0 0 10
样例输出 1
2
样例输入 2
4
0 0 0 0
样例输出 2
4
数据范围
30% 数据,1 ≤n ≤10
60% 数据,1≤ n ≤100
80% 数据,1≤ n ≤1000
100% 数据,1 ≤n≤ 5000
对于所有数据点,都有 Xi ≤ n。
#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std; const int max_n = 5e3 + ;
int n, a[max_n], p[max_n], tot = ; inline int get_num()
{
int ans = ;
bool flag = false;
char c;
while ((c = getchar()) == ' ' || c == '\n' || c == '\r');
if (isdigit(c)) ans = c - '';
else flag = true;
while (isdigit(c = getchar())) ans = ans * + c - '';
return (flag ? - : ) * ans;
} inline void solve()
{
for (int i = ; i <= n; i++)
if (!tot)
p[++tot] = ;
else
{
int wh = , maxx = ;
for (int j = ; j <= tot; j++)
if (a[i] >= p[j] && p[j] > maxx) maxx = p[j], wh = j;
if (!wh)
p[++tot] = ;
else
p[wh]++;
}
cout << tot << endl;
} int main()
{
freopen("box.in", "r", stdin);
freopen("box.out", "w", stdout);
n = get_num();
for (int i = ; i <= n; i++) a[i] = get_num();
sort(a + , a + + n); solve();
}
怎么没法对齐了。。
我的做法:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define maxn 5005
using namespace std;
int n;
int a[maxn];
int vis[maxn];
int ans = ,m =; int main(){
freopen("box.in","r",stdin);
freopen("box.out","w",stdout);
scanf("%d",&n);
for (int i=;i<=n;i++)
scanf("%d",&a[i]);
sort(a+,a+n+); memset(vis,,sizeof(vis));
for (int i=;i<=n;i++)
if (vis[i]==){
ans++;
m = ;
vis[i] = ;
for (int j = i+;j<=n;j++)
if ((vis[j]==) && (a[j]>=m)){
vis[j] = ;
m++;
}
}
printf("%d",ans);
fclose(stdin);
fclose(stdout);
}
题目描述
A 校有着神奇的住宿制度,不分男女宿舍,所有 n 个学生被统一分到两栋宿舍楼中。作为年轻人,学生之间心生爱慕之情是很正常。我们用爱慕值来表示两名学生之间的爱慕程度,如果两名爱慕值为 c 的学生被安排在同一宿舍楼,他们或她们便会在一起,并造成影响力为 c 的早恋事件。
每年年末,身为政教处主任的你会将所有早恋事件按照影响力从大到小排成一个列表,然后上报给校长。公务繁忙的校长只会去看列表中第一个事件的影响力,如果影响很大,他会考虑撤换政教处主任。
在详细考察了 n 个学生之间的爱慕关系后,你觉得压力很大。你要合理的将学生们分到两栋宿舍,以求产生的早恋事件影响力都比较小,以保住自己的官职。假设只要处于同一栋宿舍楼的两个人之间有爱慕关系,他们就一定会在这年的某个时候在一起。
那么,要怎么分配,才能让校长看到的那个早恋事件的影响力最小呢?这个最小值是多少?
输入格式
第一行两个整数 n 和 m,分别表示学生的数目和爱慕关系的对数。
接下来 m 行,每行为 3 个正整数 ai,bi,ci,表示学生 ai 和 bi 之间有爱慕关系,爱慕值为 ci。
数据保证 1 aibin,0 < ci ≤109,且每对爱慕关系只出现一次。
输出格式
输出一个数,为通过合理安排,校长看到的那个早恋事件的最小影响力。如果没有发生早恋事件,输出 0。
样例输入
4 6
1 4 2534
2 3 3512
1 2 28351
1 3 6618
2 4 1805
3 4 12884
样例输出
3512
数据范围
对于 30% 的数据,n≤15。
对于 70% 的数据,n≤2000,m≤50000。
对于 100% 的数据,n≤20000,m≤100000。
#include <cstdio>
#include <cstring>
#include <cmath>
#include <iostream>
using namespace std; const int max_n = + ;
const int max_m = 2e5 + ;
const int inf = 1e9; int *[max_n];
int point[max_n], nxt[max_m], v[max_m], c[max_m];
int tot = ;
int n, m;
int ANS; inline void add_edge(int x, int y, int cc)
{
tot++; nxt[tot] = point[x]; point[x] = tot; v[tot] = y; c[tot] = cc;
tot++; nxt[tot] = point[y]; point[y] = tot; v[tot] = x; c[tot] = cc;
} bool dfs(int now, int color)
{
*[now] = color;
for (int i = point[now]; i; i = nxt[i])
if (c[i] > ANS)
{
if (*[v[i]] == -)
{
if (!dfs(v[i], color ^ )) return false;
}
else
if (*[v[i]] == color) return false;
}
return true;
} inline bool check()
{
for (int i = ; i <= n; i++) *[i] = -;
for (int i = ; i <= n; i++)
if (*[i] == -)
if (!dfs(i, ))
return false;
return true;
} inline int getnum()
{
int ans = ;
bool flag = false; char c;
while ((c = getchar()) == ' ' || c == '\n' || c == '\r');
if (c == '-') flag = true; else ans = c - '';
while (isdigit(c = getchar())) ans = ans * + c - '';
return (flag ? - : ) * ans;
} int main()
{
freopen("love.in", "r", stdin);
freopen("love.out", "w", stdout);
n = getnum(); m = getnum();
for (int i = ; i <= m; i++)
{
int x, y, cc;
x = getnum(); y = getnum(); cc = getnum();
add_edge(x, y, cc);
}
int l = , r = inf;
while (l < r)
{
int mid = (l + r) >> ;
ANS = mid;
if (check())
r = mid;
else
l = mid + ;
}
cout << l << endl;
}