F - 6 HDU - 1016
深搜问题DFS
//题意:1-n个数排列,使相邻或首位两个数之和为素数,按字典顺序打印结果。
#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
int n;
int b[25]; //访问标记,下标对于所表示的数字,元素值0为未使用,1为已使用
int num[25];
int prime(int a) //判断素数
{
for (int i = 2; i <= sqrt(a); ++i)
{
if (a%i == 0)
{
return 0;
}
}
return 1;
}
void dfs(int k) //0-20
{
if (k == n && prime(num[k] + num[1])==1) //深度K到了n,并且最后一个和第一个也满足条件
{
for (int i = 1; i < n; ++i)
{
cout << num[i] << ' '; //输出结果
}
cout << num[n]<< endl; //注意最后一个数字后面不能有空格
}
else
{
for (int i = 2; i <= n; ++i)
{
if (b[i]==0 && prime(num[k] + i)==1) //i没被用过,并且放入能满足条件
{
num[k + 1] = i; //放入
b[i] = 1; //标记为已用
dfs(k + 1); //进行下一深度
b[i] = 0; //若回溯了则消除标记
}
}
}
}
int main()
{
int caseN = 1;
while (cin >> n)
{
memset(b, sizeof(b), 0);
num[1] = 1;
b[1] = 1;
cout << "Case " << caseN << ":" << endl;
++caseN;
dfs(1);
cout << endl;
}
return 0;
}
H - 8 UVA - 11264
贪心问题——最大硬币种类
#include <iostream>
using namespace std;
int main()
{
int p[1005];
int T, n;
cin >> T;
while (T--)
{
cin >> n;
for (int i = 0; i < n; ++i)
{
cin >> p[i];
}
if (n == 1 || n == 2) cout << n << endl;
else
{
int s = p[0];
int N = 2;
for (int i = 1; i < n - 1; ++i)
{
if (s < p[i] && s + p[i] < p[i + 1])
{
s += p[i];
++N;
}
}
cout << N << endl;
}
}
}
I - 9 HDU - 2068
错排问题
#include <iostream>
using namespace std;
long long list[25]={1,0};//要用long long
void D()//求i个数错排有多少种
{
for(int i=2;i<=25;i++)
list[i]=(i-1)*(list[i-1]+list[i-2]);
}
long long c(int n,int m) //组合数
{
long long s=1;
for(int i=1;i<=m;i++)
s=s*(n-i+1)/i;
return s;
}
int main()
{
D();
int n;
long long total;
while(cin>>n,n)
{
total=0;
for(int i=0;i<=n/2;i++)
{
total+=c(n,i)*list[i];
}
cout<<total<<endl;
}
}
J - 0 HDU - 1166
//线段树
思路:建树(理解好下标,及递归过程)、add和sub使用同一个函数,从上往下更新数据、query查询过程理解好,以后可直接套用模板
ps:输入数据量大时应用scanf_s避免超时,注意字母l和数字1,在编译器宋体下容易认错!!!
#include <iostream>
using namespace std;
const int maxn = 50005;
int n; //n个数
int p[50005];
int s;
struct node
{
int l;
int r;
int sum;
}t[maxn<<2];
void build(int l, int r,int idx ) //l:左边界,r:右边界,idx:下标
{
t[idx].l = l;
t[idx].r = r;
if (l==r)
{
t[idx].sum = p[l];
return;
}
else
{
int mid = (t[idx].l + t[idx].r) >> 1;
build(l, mid, (idx << 1) + 1); //左子树;重点理解下标idx的变化
build(mid + 1, r, (idx << 1) + 2); //右子树
t[idx].sum = t[(idx << 1) | 1].sum + t[(idx << 1) + 2].sum;
}
}
void query(int l, int r, int idx) //查询
{
if (l <= t[idx].l&&r >= t[idx].r)
{
// cout << "s=s+t[idx].sum=" << s << '+' << t[idx].sum<<endl;
s += t[idx].sum;
}
else
{
int mid = (t[idx].l + t[idx].r) >> 1;
if (r <= mid)
{
query(l, r, (idx << 1) | 1);
}
else if (l > mid)
{
query(l, r, (idx << 1) + 2);
}
else
{
query(l,mid, (idx << 1) | 1); //
query(mid+1, r, (idx << 1) + 2); //
}
}
}
void update(int i, int idx, int val)
{
t[idx].sum += val;
if (t[idx].l == i && i == t[idx].r) return;
else
{
int mid = (t[idx].l + t[idx].r) >> 1;
if (i <= mid) update(i, (idx << 1) | 1, val);
else update(i, (idx << 1) +2, val);
}
}
int main()
{
int ans = 1;
int T;
cin >> T;
while (T--)
{
cout << "Case " << ans++<<":" << endl;
cin >> n;
for (int i = 1; i <= n; ++i)
{
cin >> p[i];
}
build(1, n, 0);
/* for (int i = 0; i < 30; ++i)
{
cout << t[i].sum << ' ';
}cout << endl;*/
char op[10];
while ( cin>>op)
{
if (op[0] == 'E') break;
int a, b;
scanf_s("%d %d", &a, &b);
// cin >> a >> b; //超时
if (op[0] == 'Q')
{
s = 0;
query(a, b, 0);
printf("%d\n", s);
// cout << s << endl;
}
else if (op[0] == 'A')
{
update(a, 0, b);
}
else if (op[0] == 'S')
{
update(a, 0, -b);
}
/* for (int i = 0; i < 30; ++i)
{
cout << t[i].sum << ' ';
}cout << endl<<endl;*/
}
}
}