http://acm.hdu.edu.cn/showproblem.php?pid=3477
题目描述略。微积分题,推导过程如下:
-dT/dt=k(T-E) (T为汤的温度,E为环境温度,由Hint里的 Newton’s law of cooling知k是常数。)
积分得 -[dT/(T-E)=[kdt (“[” 表示积分号……)
化简得ln(1/(T-E)) = kt+C
整理得1/(T-E) = Cexp(kt)
当t=0时,求出C=1/(T-E)=1/(u0-ua)
k=(ln(u0-ua)-ln(u1-u1))/t1
T=1/(Cexp(kt))+E
就都可以算了
注意要特殊判断ua-u0,否则有的地方会除零
代码:
#include <cstdio>
#include <cstdio>
#include <cstdlib>
#include <math.h>
#include <algorithm>
using namespace std;
const double EPS=1e-5;
int main()
{
int cs, n, op, b;
double ua, u0, u1, t1;
double k, C;
scanf("%d", &cs);
for (int css=1; css<=cs; css++)
{
scanf("%lf%lf%lf%lf%d", &ua, &u0, &u1, &t1, &n);
k=(log(u0-ua)-log(u1-ua))/t1;
C=1.0/(u0-ua);
printf("Case %d:\n", css);
for (int i=0; i<n; i++)
{
scanf("%d%d", &op, &b);
if (op==0)
{
if (fabs(ua-u0)<EPS)
printf("0.00\n");
else
printf("%.2lf\n", log(1.0/(C*(b-ua)))/k);
}
else
{
if (fabs(ua-u0)<EPS)
printf("%.2lf\n", ua);
else
printf("%.2lf\n", 1/(C*exp(k*b))+ua);
}
}
printf("\n");
}
return 0;
}
HS BDC
http://acm.hdu.edu.cn/showproblem.php?pid=3472
题目大意:
给出一些单词,有些单词可以翻转使用,问所有能不能首尾相接(上一个单词尾字母=后一个单词首字母)连成一个串。
题目分析:
今天第一次写混合图的欧拉回路判断。
参考资料:http://www.cnblogs.com/ylfdrib/archive/2010/08/21/1805201.html
这道题要求的是欧拉路径,也就是原图中可能不存在欧拉回路的。找两个degree为奇数的点,连一条边就可以了。
注意用一个并查集先判断一下基图是否连通。
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <limits.h>
#include <algorithm>
using namespace std;
#define maxn 30
int g[28][29]; //26+2
int f[28][28];
int deg[28];
int father[28];
bool show[28];
void MakeSet(int a)
{
father[a]=a;
}
int Find(int a)
{
if(father[a]==a) return a;
return father[a]=Find(father[a]);
}
bool Same(int a,int b)
{
return Find(a)==Find(b);
}
void Union(int a,int b)
{
father[Find(a)]=Find(b);
}
void order(char &ch1, char &ch2)
{
if (ch1>ch2)
{
char t=ch1;
ch1=ch2;
ch2=t;
}
}
bool init()
{
int n, tag, odd;
char word[30], ch1, ch2;
scanf("%d", &n);
memset(g, 0, sizeof(g)); //只存无向边的任意定向
memset(deg, 0, sizeof(deg));
memset(show, 0, sizeof(show));
for (int i=0; i<26; i++)
MakeSet(i);
for (int i=0; i<n; i++)
{
scanf("%s%d", word, &tag);
ch1=word[0];
ch2=word[strlen(word)-1];
if (ch1==ch2)
continue;
if (tag==1)
{
order(ch1, ch2);
g[ch1-'a'][ch2-'a']++;
// printf("ch1=%c ch2=%c\n", ch1, ch2);
}
deg[ch1-'a']--;
deg[ch2-'a']++;
show[ch1-'a']=show[ch2-'a']=true;
Union(ch1-'a', ch2-'a');
}
for (int i=0; i<26; i++)
if (show[i])
{
for (int j=i+1; j<26; j++)
if (show[j] && !Same(i, j)) return false; //不连通
break;
}
odd=0;
for (int i=0; i<26; i++)
if (show[i] && deg[i]%2!=0)
{
if (odd==0) ch1=i+'a';
else if (odd==1) ch2=i+'a';
odd++;
if (odd>2) return false;
}
if (odd==1) return false;
else if (odd==2)
{
order(ch1, ch2);
g[ch1-'a'][ch2-'a']++;
deg[ch1-'a']--;
deg[ch2-'a']++;
}
return true;
}
void build_graph(int &total)
{
int src=26, dst=27;
total=0;
for (int i=0; i<26; i++)
if (show[i] && deg[i]!=0)
{
if (deg[i]<0)
{
g[src][i]=(-deg[i])/2;
total+=g[src][i];
// printf("src %c %d\n", i+'a', g[src][i]);
}
else
{
g[i][dst]=deg[i]/2;
// printf("%c dst %d\n", i+'a', g[i][dst]);
}
}
// for (int i=0; i<26; i++)
// { for (int j=0; j<26; j++)if (g[i][j]>0)printf("(%c %c) %d\n ",i+'a', j+'a',g[i][j]);}
}
int EdmondsKarp(int n,int src,int dst)
{
int d[maxn]={},p[maxn],r[maxn]={},c[maxn]={n};
int flow=0,delta=INT_MAX,h[maxn],v=src;
memset(f, 0, sizeof(f));
p[src]=-1;
while(d[src]<n)
{
bool flag=true;;
h[v]=delta;
for(int i=r[v];i<n;i++)
if(g[v][i]>f[v][i]&&d[v]==d[i]+1)
{
if(delta>g[v][i]-f[v][i]) delta=g[v][i]-f[v][i];
flag=false;
r[v]=i;p[i]=v;v=i;
break;
}
if(flag)
{
int t=n-1;
for(int i=0;i<n;i++)
if(t>d[i]&&f[v][i]<g[v][i]) {t=d[i];r[v]=i;}
if(--c[d[v]]==0) break;
d[v]=t+1;
c[d[v]]++;
if(p[v]!=-1) {v=p[v];delta=h[v];}
}
else if(v==dst)
{
flow+=delta;
while(p[v]!=-1)
{
f[v][p[v]]-=delta;
f[p[v]][v]+=delta;
v=p[v];
}
delta=INT_MAX;
}
}
return flow;
}
int main()
{
int cs, total;
scanf("%d", &cs);
for (int css=1; css<=cs; css++)
{
printf("Case %d: ", css);
if (!init())
{
printf("Poor boy!\n");
continue;
}
build_graph(total);
if (EdmondsKarp(28, 26, 27)!=total)
printf("Poor boy!\n");
else
printf("Well done!\n");
}
return 0;
}
第一次写这种题,mark一下~